# Paycoinly > Dinosaurs are cool This file contains all documentation content in a single document following the llmstxt.org standard. ## Introduction **Paycoinly** is best understood as a crypto payment infrastructure layer that lets businesses accept, route, and withdraw payments across multiple crypto assets (stablecoins, native chain tokens, and even memecoins), while also supporting both online and offline commerce flows. In simpler terms: it's a "payment gateway for crypto" similar in spirit to Stripe or PayPal - but built for blockchain-native money movement. ### What is Paycoinly? **Paycoinly** is a multi-chain crypto payment gateway designed to help businesses: - Accept payments in stablecoins (e.g., USDT/USDC-type assets) - Accept native chain tokens (ETH, BNB, etc.) - Potentially accept memecoins or long-tail tokens - Potentially accept tokenized real world assets (Gold, NVDA, AAPL, etc.) - Process online payments (checkout, subscriptions, donations, tipping) - Support fund flows in and out (deposit + withdrawal systems) - Integrate crypto payments into real-world business models (not just "accept crypto") - Provide multi-currency support, allowing: - Pricing in a merchant’s preferred base currency - Real-time display of prices in the customer’s local currency At its core, it acts as a bridge between blockchain assets and real-world business cash flow systems. ### Who is Paycoinly for? **Paycoinly** is built for any individual, business, or platform that wants to integrate crypto payments without dealing with blockchain complexity. It is especially useful for: - **Ecommerce businesses** (physical and digital goods) - **Subscription-based services** (SaaS, memberships, content platforms) - **Donation platforms and creators** (buy me a coffee, tipping systems) - **Marketplaces and freelance platforms** (escrow-based transactions, payouts) - **Online gaming and casino platforms** (deposits, withdrawals, wallet systems) - **Local businesses** (POS use cases) such as coffee shops, gyms, barber shops, laundromats, and retail stores - **Fintech and Web3 applications** that need programmable crypto payment infrastructure ### How does Paycoinly generate revenue? **Paycoinly** earns a 1% fee on each transaction processed through its platform. ### What network does Paycoinly support? - Ethereum Mainnet - Polygon - Arbitrum - BNB Smart Chain - Avalanche Coming soon - Bitcoin - Tron - Solana --- ## How Does Payment Flow Work With Your System import Premium from '@site/src/components/premium' # How Does Payment Flow Work With Your System The flow described on this page serves as the foundation for all payment integrations - [Manual Setup](/docs/integrations/manual), [Woocommerce](/docs/integrations/woocommerce), [Wordpress](/docs/integrations/wordpress) and [Manual Setup Best Practices](/docs/best-practices/manual). Each integration is built upon the core workflow and logic outlined here. Here are some elements showing in the diagram with links to detailed information. - [Best practice - step 1](/docs/best-practices/manual#step-1) - [Payment Token Generation API](/docs/api-reference/payment-token.mdx) - [Callback](/docs/integrations/manual#add-a-webhook-to-your-backend) - [Notify success](/docs/integrations/manual#receive-payment-success-event-in-your-frontend) ```mermaid sequenceDiagram autonumber actor user as User participant yourFrontend as Your Frontend participant paycoinlyUI as Paycoinly Payment UI participant backend as Your System participant paycoinly as Paycoinly user->>yourFrontend: Click Pay button rect rgb(255, 191, 191) note right of yourFrontend: Best practice - step 1 yourFrontend->>backend: order id backend->>backend: Determine price using order id rect rgb(191, 223, 255) note right of backend: Payment Token Generation API backend->>paycoinly: price, order id paycoinly->>backend: payment token end backend->>backend: Determine Paycoinly payment UI url using payment token backend->>paycoinlyUI: Redirect to Paycoinly payment UI url end user->>paycoinlyUI: Make the payment paycoinlyUI->>paycoinly: Submit the payment paycoinly->>paycoinly: Process the payment rect rgb(255, 191, 255) note right of backend: Callback paycoinly->>backend: Trigger callback URL with order id backend->>backend: Record the payment end paycoinly->>paycoinlyUI: Notify success rect rgb(191, 255, 200) note right of yourFrontend: 👑 Premium paycoinlyUI->>yourFrontend: Notify success end ``` --- ## How Does Withdrawal Flow Work With Your System import Premium from '@site/src/components/premium' # How Does Withdrawal Flow Work With Your System The flow diagram provides a clear overview of how the withdrawal process integrates with your system and serves as the foundation for [Withdrawal Integration](/docs/integrations/withdraw) and [Withdrawal Integration Best Practices](/docs/best-practices/withdraw). Here are some elements showing in the diagram with links to detailed information. - [Callback URL](/docs/integrations/withdraw#add-a-webhook-to-your-backend) - [Best practices - step 1](/docs/best-practices/withdraw#step-1) - [Initiate withdrawal process](/docs/integrations/withdraw#initiate-withdrawal-process) - [Getting Customer Balances API](/docs/api-reference/get-customer-balance) - [Withdrawal Token Generation API](/docs/api-reference/withdraw-token) - [Notify](/docs/integrations/withdraw#add-javascript-code) - [Process withdrawal request](/docs/integrations/withdraw#add-a-backend-endpoint-to-process-withdrawal-request) - [Withdrawal Request API](/docs/api-reference/withdraw-request) ```mermaid sequenceDiagram autonumber actor user as User participant yourFrontend as Your Frontend participant paycoinlyUI as Paycoinly Withdrawal UI participant backend as Your System participant paycoinly as Paycoinly rect rgb(255, 191, 191) note right of backend: Callback URL paycoinly->>backend: Trigger Callback URL with payment data backend->>backend: Adjust user balance end user->>yourFrontend: Click Withdraw button yourFrontend->>backend: Initiate withdrawal process rect rgb(235, 191, 255) note right of paycoinlyUI: Best practices - step 1 rect rgb(255, 222, 191) note right of backend: Initiate withdrawal process rect rgb(191, 229, 255) note right of backend: Getting Customer Balances API backend->>paycoinly: Get user balances paycoinly->>backend: user balances end backend->>backend: Get user id hash rect rgb(191, 255, 234) note right of backend: Withdrawal Token Generation API (👑 Premium) backend->>paycoinly: user id hash, his/her balance paycoinly->>backend: withdrawal token end end backend->>backend: Determine Paycoinly withdrawal UI url using withdrawal token backend->>paycoinlyUI: Redirect to Paycoinly withdrawal UI end user->>paycoinlyUI: Submit withdrawal coin and amount rect rgb(191, 208, 255) note right of yourFrontend: Notify paycoinlyUI->>yourFrontend: Notify withdrawal data yourFrontend->>backend: withdraw data end rect rgb(255, 191, 234) note right of backend: Process withdrawal request backend->>backend: Ensure the withdrawal amount does not exceed his/her balance rect rgb(217, 255, 191) note right of backend: Withdrawal Request API (👑 Premium) backend->>paycoinly: withdraw data paycoinly->>backend: success end backend->>backend: Deduct his/her balance end paycoinly->>paycoinlyUI: Notify withdraw request has been created user->>paycoinlyUI: withdraw paycoinlyUI->>paycoinly: submit withdraw paycoinly->>paycoinly: send funds to his/her wallet paycoinly->>paycoinlyUI: success ``` --- ## Donation This page explains how to integrate Paycoinly into your platform to accept donations and "Buy Me a Coffee" contributions from your users, without recording their payments in your system. ### Configure option Navigate to **Payments** > **Settings** > **Basic** and select **Okay Not To Have Payer Information** ![image](./img/wp-2.png) ### Enter price information Navigate to **Payments** > **Integration** and enter **Price**, **Currency** and **Local Currency**. ### Integrate Paycoinly UI to your project Navigate to **Project** tab, copy the HTML snippet showing there and paste it into your frontend code. --- ## Manual Setup import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import Premium from '@site/src/components/premium' # Manual Setup Manual Integration enables developers to connect Paycoinly payment services to their platform using a custom-built integration approach, allowing your users to make payments through Paycoinly and have your platform record them. ### Prerequisites Before you can start manual integration, ensure you have the following: - **How would you like to receive customer information?** is set to one of the followings in **Payments** > **Settings** > **Basic** - **I Want To Know Who Paid** - **My Customers Can Claim Their Money Back** - **On which platform is your service running?** is set to **None** in **Payments** > **Settings** > **Integration** ![Image](./img/manual-1.png) ### Add a webhook to your backend PayCoinly will call this endpoint when the payment is successfully completed. Implement the necessary backend logic to record the payment in your system. #### Endpoint The webhook URL should be the one you set in **Settings** > **Integration** > **Callback URL** in your payment. ![Image](./img/manual-2.png) The webhook should be a **POST** route. #### Header The webhook will receive a request containing `x-api-key` header. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. :::tip[Security Tip] To secure this webhook and prevent unauthorized or arbitrary access - Validate that the `x-api-key` header in the incoming request exactly matches with the above value. - Only allow the route to be executed if this API key is correct. Otherwise, reject the request. ::: #### Body The endpoint expects the request body to contain the below fields. - basic fields about the payment - fields passed to [`metadata`](/docs/api-reference/payment-token#body) when generating a payment token in the [next step](#get-a-payment-token) All fields are in string format. | Field | Description | | ----------------- | ------------------------------------------------------------------------------------------------------------------------- | | chainId | Chain ID of the payment coin | | symbol | Symbol of payment coin | | totalPaid | Total amount of coin paid in gwei (or the smallest unit) | | netPaid | Paid amount after transaction fee | | claimable | Amount to your users to claim if the payment is set to **My Customers Can Claim Their Money Back**, otherwise `"0"` | | txLink | A link to payment details | | `metadata` fields | [`metadata`](/docs/api-reference/payment-token#body) fields in destructured | ### Get a payment token In your backend, make a request to [Payment Token Generation API](/docs/api-reference/payment-token) to generate a payment token, which will be used in the next step. ### Add a payment UI to your frontend Use the following URL to show Paycoinly payment page. ``` https://app.paycoinly.xyz/pay?token={token} ``` where `token` is the payment token obtained from [the above step](#get-a-payment-token). Here is a sample HTML snippet that you can use to embed the payment UI. ```HTML ``` ```HTML ``` ### Receive payment success event in your frontend Add the following code to your frontend to receive payment success event. ```javascript window.addEventListener('message', (event) => { if (event.origin !== 'https://app.paycoinly.xyz') { return; } if (event.data.type === 'PAYCOINLY_PAYMENT_COMPLETE') { // event.data.payload contains price, currency and metadata console.log(event.data.payload); } }); ``` Please see [Success Event](/docs/appendix/success-event) page to check how this event is triggered. ### Best practices [This section](/docs/best-practices/manual) also describes best practices for implementing manual integration. --- ## How to use Paycoinly In Point-of-Sales and Local Businesses Paycoinly is also a good choice to local businesses like local stores, barbers' shops, laundries, gyms, coffee shops and other physical retail locations looking to accept cryptocurrency payments. ### Configure POS option Navigate to **Payments** > **Settings** > **Basic** and select **Okay Not To Have Payer Information** ![image](./img/wp-2.png) ### Enter price information Navigate to **Payments** > **Integration** and enter **Price**, **Currency** and **Local Currency**. ### Show the QR code to your customer Navigate to **Point of Sale** tab and click **Show** button to show the QR code to your customer to receive the payment. ![image](./img/pos-1.png) --- ## Withdrawal Integration import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import Premium from '@site/src/components/premium' # Withdrawal Integration Withdrawal Integration enables developers to connect Paycoinly withdraw service to their platform, allowing your users to seamlessly withdraw their balances from Paycoinly. This feature requires subscrition. ### Prerequisites Before you can start withdrawal integration, ensure you have the following: - **How would you like to receive customer information?** is set to **My Customers Can Claim Their Money Back** in **Payments** > **Settings** > **Basic** - Provide value to **Callback URL** and **Fee** ![Image](./img/withdraw-1.png) ### Add a webhook to your backend The webhook is a payment listener which will be triggered when your customer payment is completed. Please see implement details [here](/docs/integrations/manual#add-a-webhook-to-your-backend). Additionally you need to keep record of your user's [`claimable` amount](/docs/integrations/manual#body) in your backend, and pass the user's balance when [generating a withdraw token](#get-withdrawal-token). ### Add a backend endpoint to process withdrawal request As the first among all others, you need to add a **POST** endpoint to your backend which does the following things: - handle the withdrawal logic - ask Paycoinly to make a withdrawal request so that your customers can finalize their withdrawal action using it This endpoint will be triggered when implementing the Javascript integration described in the [Add Javascript code](#add-javascript-code) step. #### Endpoint Any route you want #### Body The endpoint expects the request body to contain the data specified below. ```typescript { chainId: string symbol: string amount: string value: number currency: string wallet: string } ``` You can see the meaning of each field in the below table. | Name | Description | | -------- | ---------------------------------------- | | chainId | Chain ID of the token | | symbol | Symbol of the token | | amount | Token amount in wei (or smallest unit) | | value | Token `amount` value in `currency` | | currency | Currency of `value` (Fixed to `USD`) | | wallet | Wallet address the user will withdraw to | `chainId` and `symbol` should be the one you get from [Getting Customer Balances API](/docs/api-reference/get-customer-balance) in [Check customer balances](#check-customer-balances) step. #### Implementation - Ensure the withdrawal amount (or value) in the payload does not exceed the user balance in your system. - After validation, send a withdrawal request to [Making Withdrawal Request API](/docs/api-reference/withdraw-request). - If the response is successful (200), deduct the specified amount from the user's balance in your system. ### Initiate withdrawal process When your user initiates a balance withdrawal, your backend needs to perform following tasks. #### Check customer balances Check balances of your customers combined by making request to [Getting Customer Balances API](/docs/api-reference/get-customer-balance) in your backend. The API responds with a list of coins and their respective balances. The response includes token data like `chainId`, `symbol` which need to be used in the [next step](#get-withdrawal-token). #### Get withdrawal token Your backend should then call the [Withdrawal Token Generation API](/docs/api-reference/withdraw-token) using your user ID initiating the withdrawal, along with [his/her balance information](#add-a-webhook-to-your-backend) stored in your system. You should use the same `chainId` and `symbol` as the one you retrieved in the [previous step](#check-customer-balances) when passing the balance information to the API. The API returns a withdrawal token, which is used to link and launch the Paycoinly Withdrawal UI in the [next step](#add-a-withdraw-ui-to-your-frontend). :::info It is the **responsibility of your system** to maintain and track the withdrawal eligibility of each user. Paycoinly does not store or manage individual user balances within your platform; it only maintains the aggregate balance of all your users combined. Therefore, when generating a withdrawal token, your backend must provide the user's available balance to [Withdrawal Token Generation API](/docs/api-reference/withdraw-token#body). Also see [how to record users' withdrawable balance](#add-a-webhook-to-your-backend) in your system. ::: ### Implement frontend #### Add a withdraw UI to your frontend Show the withdraw UI to your users using the following URL ``` https://app.paycoinly.xyz/claim/{token} ``` where `token` is the withdraw token obtained from the [previous step](#get-withdrawal-token). Here is a sample HTML snippet that you can use to embed the withdraw UI. ```HTML ``` ```HTML ``` #### Add Javascript code Add the following Javascript to your frontend to interact with the withdrawal UI. ```javascript window.addEventListener('message', (event) => { if (event.origin !== 'https://app.paycoinly.xyz') { return; } if (event.data.type === 'PAYCOINLY_REQUEST_WITHDRAW') { console.log(event.data.payload); // make a request to your backend with event.data.payload fetch('/process/withdrawal-request', { method: 'post', body: JSON.stringify(event.data.payload) }) .then(() => { console.log('Withdrawal request processed successfully'); }) } }); ``` The message event delivers a payload in `event.data.payload`, which includes the withdrawal details selected by the user. Upon message acceptance, make a call to [Process withdrawal request endpoint](#add-a-backend-endpoint-to-process-withdrawal-request), which you configured in the very first step, with the payload to submit a withdrawal request to PayCoinly. ### Best practices [This section](/docs/best-practices/withdraw) also describes best practices for implementing withdrawal integration. --- ## Woocommerce Integration This page explains how to seamlessly integrate Paycoinly with your Woocommerce store using the official [Paycoinly plugin](https://wordpress.org/plugins/paycoinly/). With this approach, there's no need for manual setup, such as adding webhooks or embedding Paycoinly UI elements - everything is fully automated and handled directly through the plugin. The plugin adds **Paycoinly** option in checkout page, and when your customers click **Place order** button, the payments are executed with the configurations you make here. ### Prerequisites Before continue, ensure you have the following: - **How would you like to receive customer information?** is set to either **I Want To Know Who Paid** or **My Customers Can Claim Their Money Back** in **Payments** > **Settings** > **Basic** ![image](./img/woo-1.png) ### Configure Woocommerce options Navigate to **Payments** > **Settings** > **Integration**, select **WordPress or WooCommerce**, and enter the domain of your Woocommerce store. ![image](./img/woo-2.png) ### Install and configure Paycoinly plugin - Install Paycoinly plugin in your Wordpress admin dashboard. ![image](./img/plugin.png) - Navigate to Paycoinly in Woocommerce Payments page. ![image](./img/woo-4.png) - Check **Activate Paycoinly Gateway in Woocommerce** and provide **API Key**. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. - Select a payment in **Payments** section. All customer payments from your store will be routed to it. :::info If you see some payments disabled, it's because they are not eligible for your store. You can select a payment in Paycoinly plugin which satisfies [prerequisites](#prerequisites) and has the correct [Woocommerce options](#configure-woocommerce-options) configured. ::: - Click **Save Changes** button. ### Plugin actions and filters You can leverage actions and filters provided from the Paycoinly plugin to extend its functionalities on your own when your platform processes payments. Please check [WP Plugin Hooks](/docs/appendix/wordpress-plugin-hooks) for more information. --- ## Wordpress Integration This page explains how to seamlessly integrate Paycoinly with your Wordpress site using the official [Paycoinly plugin](https://wordpress.org/plugins/paycoinly/). With this approach, there's no need for manual setup, such as adding webhooks or embedding Paycoinly UI elements - everything is fully automated and handled directly through the plugin. Payments triggered via `paycoinly` shortcode, which is described [in the below](#place-paycoinly-ui), on any other Wordpress page except the Woocommerce checkout page are executed with the configurations you make here. ### Configure Wordpress options You can integrate Paycoinly into your WordPress site using one of the following two options: - **Keep payer information**: Choose this option if you want to identify who made each payment and have your platform record customer payment details. For more information, see [Keeping payer information](#keeping-payer-information) section. - **Anonymous payments**: Choose this option if you do not require customer details and only wish to accept payments, similar to a donation model. For more information, see [Anonymous payment](#anonymous-payment)t section. #### Keeping payer information - Please set **How would you like to receive customer information?** to either **I Want To Know Who Paid** or **My Customers Can Claim Their Money Back** in **Payments** > **Settings** > **Basic**. - Navigate to **Payments** > **Settings** > **Integration**, select **WordPress or WooCommerce**, and enter the domain of your Wordpress site. ![image](./img/wp-1.png) #### Anonymous payment Please set **How would you like to receive customer information?** to **Okay Not To Have Payer Information** in **Payments** > **Settings** > **Basic**. ![image](./img/wp-2.png) ### Install and configure Paycoinly plugin - Install Paycoinly plugin in your Wordpress admin dashboard. ![image](./img/plugin.png) - Navigate to Paycoinly in Wordpress admin dashboard. ![image](./img/wp-4.png) - Enter **API Key**. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. - Select a payment in **Payments** section. All customer payments from your site will be routed to it. :::info If you see some payments disabled, it's because they are not eligible for your site. You can select a payment in Paycoinly plugin which has the correct [Wordpress options](#configure-wordpress-options) configured. ::: - Click **Save Changes** button. ### Place Paycoinly UI Please use [`paycoinly` shortcode](/docs/appendix/wordpress-plugin-hooks#shortcodes) to render UI element, enabling your users to navigate to Paycoinly payment UI. ### Plugin actions and filters You can leverage actions and filters provided from the Paycoinly plugin to extend its functionalities on your own when your platform processes payments. Please check [WP Plugin Hooks](/docs/appendix/wordpress-plugin-hooks) for more information. --- ## Getting Customer Balances This endpoint returns a list of your customers' balance per coin, which will be used by [Withdrawal Token Generation API](/docs/api-reference/withdraw-token). For more information of customer withdrawal steps, please refer to [Withdrawal Integration](/docs/integrations/withdraw#check-customer-balances) page. ### Endpoint ``` https://app.paycoinly.xyz/v1/withdraw/balance ``` It is a **GET** request. ### Query Parameters | Name | Optional | Default | Description | | -------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | currency | Yes | USD | `value` in response is calculated in the specified currency. See [Currency List](/docs/appendix/currency-list.mdx) for available values. | ### Headers ```json { "x-api-key": "", "content-type": "application/json" } ``` The request should include `x-api-key` in its header. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. ### Response Object array, whose syntax is described in the below. ```typescript title='Syntax' { amount: string; value: number; currency: string; token: { chainId: number; symbol: string; address: string | null; decimals: number; }[] ``` You can see the meaning of each field in the table below. | Name | Description | | -------- | ------------------------------------------------------------------------------------------- | | amount | Coin amount in wei (or smallest unit) | | value | Value of the coin `amount` in `currency` specified as a query parameter | | currency | Currency of `value` in the response | | chainId | Chain ID of the coin | | symbol | Symbol of the coin | | address | Address of the coin or `null` if it is the native coin of its chain like **ETH** or **BNB** | | decimals | Decimals of the coin | --- ## Payment Token Generation Your backend should call this endpoint in [Get a payment token](/docs/integrations/manual#get-a-payment-token) step, and the token will be used to display Paycoinly payment UI on your customers' side as described in [Manual Setup](/docs/integrations/manual#add-a-payment-ui-to-your-frontend) page. ### Endpoint ``` https://app.paycoinly.xyz/v1/pay/{payment-id} ``` It is a **POST** request. To see `payment-id`, navigate to the corresponding payment in the **Paycoinly dashboard** > **Payments** - the ID will be visible in your browser's URL. ![image](./img/token-1.png) ### Headers ```json { "x-api-key": "", "content-type": "application/json" } ``` The request should include `x-api-key` in its header. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. ### Body You can customize the request body to fit your specific business requirements, and you can see its syntax below. ```typescript { price: string currency?: string localCurrency?: string metadata?: {} } ``` You can see the meaning of each field in the below table. | Field | Mandatory | Default | Description | | ------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- | | price | Yes | | Service price - a numeric value representing the cost of the service | | currency | | USD | Currency in which `price` is specified. Refer to [currency list](/docs/appendix/currency-list) page. | | localCurrency | | USD | `price` will be shown in local currency on user's side. Refer to [currency list](/docs/appendix/currency-list) page. | | metadata | | | [Callback URL](/docs/integrations/manual#add-a-webhook-to-your-backend) will receive a request with this JSON value set in its body | ### Response ```json { "token": "" } ``` Use this token to [show Paycoinly payment UI](/docs/integrations/manual#add-a-payment-ui-to-your-frontend) on your frontend code showing to your customers. ### Example Below is an example of how to make a request to the endpoint using Node.js. ```javascript title="In your backend" async function generatePaymentToken() { const response = await fetch('https://app.paycoinly.xyz/v1/pay/{payment-id}', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': '{x-api-key}' }, body: JSON.stringify({ price: 100.00, currency: 'USD', localCurrency: 'EUR', metadata: { orderId: 'abc123', customerId: 'user789' } }) }); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const { token } = await response.json(); return token; } ``` --- ## Making Withdrawal Request import Premium from '@site/src/components/premium' # Making Withdrawal Request For your customers to withdraw their balance, your backend should call this endpoint to generate a withdrawal request, which will be then showing in Paycoinly withdraw UI, allowing your customers to finalize their withdrawal with it. You need to subscribe to to use this API. For more information of customer withdrawal steps, please refer to [Withdrawal Integration](/docs/integrations/withdraw#implementation) page. ### Endpoint ``` https://app.paycoinly.xyz/v1/withdraw ``` It is a **POST** request. ### Headers ```json { "x-api-key": "", "content-type": "application/json" } ``` The request should include `x-api-key` in its header. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. ### Body You can see the syntax of the request body below. ```typescript { chainId: string symbol: string wallet: string currency?: string | null amount: string user: string } ``` The meaning of each field is provided in the table below. | Name | Optional | Description | | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | chainId | | Chain ID of the token | | symbol | | Symbol of the token | | wallet | | Wallet address the user will withdraw to | | amount | | Token amount in wei (or smallest unit) if `currency` is not specified, otherwise withdraw amount in `currency` | | currency | Yes | If not specified, the withdrawal `amount` is in the smallest unit of the token. Otherwise, the withdrawal `amount` is in the specified `currency`. | | user | | Id of your customer in your system who is performing the withdrawal | For values of each field, please refer to [Withdrawal Integration](/docs/integrations/withdraw#body) page. :::info `user` should be the same value as the one used in the [Withdrawal Token Generation API](/docs/api-reference/withdraw-token#body). ::: ### Response | Status Code | Description | | ----------- | ---------------------------------------------------------------------------- | | 200 | Success | | 400 | Possible response: `No Token Found` or `Withdraw amount exceeds the balance` | | 403 | `You are not a premium user` | --- ## Withdrawal Token Generation import Premium from '@site/src/components/premium' # Withdrawal Token Generation For your customers to withdraw their balance, your backend should call this endpoint to generate a withdrawal token, which is used to show withdrawal UI to your customer. You need to subscribe to to use this API. For more information of customer withdrawal steps, please refer to [Withdrawal Integration](/docs/integrations/withdraw#get-withdrawal-token) page. ### Endpoint ``` https://app.paycoinly.xyz/v1/withdraw/token ``` It is a **POST** request. ### Headers ```json { "x-api-key": "", "content-type": "application/json" } ``` The request should include `x-api-key` in its header. Please check [this page](/docs/appendix/api-key) to get API key in your Paycoinly dashboard. ### Body You can see the syntax of the request body below. ```typescript { user: string; balances: { amount: string chainId: number symbol: string }[] } ``` The meaning of each field is provided in the table below. | Name | Description | | ------- | -------------------------------------------------------------------- | | user | Id of your customer in your system who is performing the withdrawal. | | amount | Token amount in wei (or smallest unit) | | chainId | Chain ID of the token | | symbol | Symbol of the token | `chainId` and `symbol` should be the one you retrieved from [Getting Customer Balances API](/docs/api-reference/get-customer-balance#response). :::tip[Security Tip] - Regarding `user` field, it is recommended to use hashed format to prevent enumeration of user ids. - **IMPORTANT:** Please ensure that you do not specify `balances` exceeding the amount your user is eligible to withdraw. ::: :::info[] You can't provide greater value than the `amount` returned from [Getting Customer Balances API](/docs/api-reference/get-customer-balance#response). ::: ### Response ```json { "token": "" } ``` Use this token to [show Paycoinly withdrawal UI](/docs/integrations/withdraw#add-a-withdraw-ui-to-your-frontend) on your frontend code showing to your customers. --- ## Best Practices for Manual Setup This page describes a streamlined approach to align steps described in [Manual Setup](/docs/integrations/manual.mdx) guide, without making your backend complicated going forth and back. Please see [How Does Payment Flow Work With Your System](/docs/how-work/payment.mdx) to get more context of it. ### Step 1 Make a **GET** endpoint on your backend which has the following implementation in it: - Accept **order ID** (or service ID) query param. - Determine price from **order ID**. - [Request a payment token](/docs/api-reference/payment-token#body) with the price included in its body. - Redirect to the following route using that token, which shows PayCoinly payment UI. ``` https://app.paycoinly.xyz/pay?token={token} ``` ### Step 2 Connect a button in your customer page to **Step 1** endpoint with **order ID** query param included. ```HTML ``` :::info By sending **order ID** query parameter to **Step 1** endpoint and having your backend determine the price from it, you can hide the price logic, making the integration secure and protected against manipulation through arbitrary amount in the browser. ::: --- ## Best Practices for Withdrawal Integration This page describes a streamlined approach to align steps described in [Withdrawal Integration](/docs/integrations/withdraw) guide, without making your backend complicated going forth and back. Please see [How Does Withdrawal Flow Work With Your System](/docs/how-work/withdraw) to get more context of it. ### Step 1 Make a **GET** endpoint on your backend which has the following implementation in it: - [Initiate withdrawal process](/docs/integrations/withdraw#initiate-withdrawal-process). - Redirect to the following route using the withdrawal token from the previous step, which shows PayCoinly withdrawal UI. ``` https://app.paycoinly.xyz/claim?token={token} ``` ### Step 2 Connect a button in your customer page to **Step 1** endpoint. ```HTML ``` --- ## Hook into Paycoinly Plugin You can use third-party Wordpress plugins such as - [WPCode](https://wordpress.org/plugins/insert-headers-and-footers/) - [Code Snippets](https://wordpress.org/plugins/code-snippets/) to easily add hooks into [Paycoinly plugin](/docs/appendix/wordpress-plugin-hooks) without modifying your files or writing a full custom plugin. --- ## How to Get API Key in Paycoinly Dashboard Go to Paycoinly dashboard, click **API Key** button in the navigation bar and the API Key will be copied to your clipboard. ![image](./img/apikey-1.png) :::tip[Security Tip] Never share your API Key to the others and keep it safe. ::: --- ## Currency List - Request body of [Payment token generation API](/docs/api-reference/payment-token#body) includes `currency` and `localCurrency` - Query parameter and response of [Customer Token Balance API](/docs/api-reference/get-customer-balance.mdx) includes `currency` They refer to the value in the table below. | Value | Description | | ----- | --------------------- | | AUD | Australian Dollar | | BRL | Brazilian Real | | CAD | Canadian Dollar | | CHF | Swiss Franc | | CLP | Chilean Peso | | CNH | Chinese Yuan Renminbi | | COP | Colombian Peso | | EUR | Euro | | GBP | British Pound | | HKD | Hong Kong Dollar | | IDR | Indonesian Rupiah | | INR | Indian Rupee | | JPY | Japanese Yen | | KRW | South Korean Won | | MXN | Mexican Peso | | NOK | Norwegian Krone | | NZD | New Zealand Dollar | | PEN | Peruvian Sol | | PHP | Philippine Peso | | SEK | Swedish Krona | | SGD | Singapore Dollar | | TWD | Taiwan Dollar | | TRY | Turkish Lira | | USD | United States Dollar | | ZAR | South African Rand | --- ## Payment Success Event on Frontend import Premium from '@site/src/components/premium' # Payment Success Event on Frontend When Paycoinly processes a payment successfully, it triggers a success event to your frontend with the data your backend passed to Paycoinly when [generating the payment token](/docs/api-reference/payment-token). The event payload contains [information](/docs/api-reference/payment-token#body) about price, currency and metadata of the completed transaction. The frontend can then update the UI to reflect the successful payment based on the event payload and provide appropriate feedback to the user, eliminating the needs for requesting backend for updates. This feature is available to users. The example shows how you can access the event payload. ```javascript window.addEventListener('message', (event) => { if (event.origin !== 'https://app.paycoinly.xyz') { return; } if (event.data.type === 'PAYCOINLY_PAYMENT_COMPLETE') { // event.data.payload contains price, currency and metadata console.log(event.data.payload); } }); ``` --- ## Wordpress Plugin Actions, Filters and Shortcode The Paycoinly plugin provides several filters, actions and shortcode which allow you to extend and customize its payment processing functionality to meet your specific requirements. ### Glossary - **Woocommerce payment** refers to a payment initiated by clicking the **Place Order** button on the Woocommerce checkout page. - **Wordpress payment** refers to a payment triggered via the [`paycoinly`](#paycoinly) shortcode on Wordpress page other than the Woocommerce checkout page. ### Actions #### paycoinly_before_handle_wc_payment This action is triggered just before your platform records customer's Paycoinly payment in the callback endpoint. It is used for [Woocommerce payments](#glossary) only. ```php add_action('paycoinly_before_handle_wc_payment', 'before_handle_wc_payment'); function before_handle_wc_payment($payload) { // invoke your custom operation print_r($payload); echo $payload['order_id']; echo $payload['user_id']; echo 'woocommerce is going to record the payment'; } ``` | Arg | Type | Description | | ------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | payload | `array('order_id' => string, 'user_id' => string)` | Paycoinly invokes the callback endpoint, including the following data in the request body. `order_id` and `user_id` are corresponding values in your Woocommerce store | #### paycoinly_handle_payment This action is triggered just after your platform records customer's Paycoinly payment in the callback endpoint. It is used for both [Wordpress and Woocommerce payments](#glossary). ```php add_action('paycoinly_handle_payment', 'after_handle_payment'); function after_handle_payment($payload, $mode) { // invoke your custom operation print_r($payload); echo $payload['order_id']; echo $payload['user_id']; if ($mode == 'wc') { echo 'woocommerce recorded a payment'; } else { echo 'wordpress recorded a payment'; } } ``` | Arg | Type | Description | | ------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | payload | `array('order_id' => string, 'user_id' => string)` | Paycoinly invokes the callback endpoint, including the following data in the request body. `order_id` and `user_id` are corresponding values in your Woocommerce store | | wc | string | `wc` if the payment is for Woocommerce, otherwise `wp` | ### Filters #### paycoinly_order_price This filter is used to calculate price of the order before Paycoinly shows payment UI to your customers. It is used for [Wordpress payments](#glossary) only. Please refer to [Wordpress Integration](/docs/integrations/wordpress#place-paycoinly-ui) page to get more understanding and workflow of it. ```php title='Example' add_filter('paycoinly_order_price', 'get_order_price', $order_id); function get_order_price($order_id) { // calculate the price based on $order_id if ($order_id == 'basic') { return 10; } else if ($order_id == 'pro') { return 30; } else if ($order_id == 'enterprise') { return 50; } } ``` | Arg | Type | Description | | -------- | ------ | ---------------------------------------------------------------------------------------- | | order_id | string | Data on which you want to calculate the price based. `order_id` is passed from shortcode | #### paycoinly_on_complete This filter is used to define the custom Javascript code which will be triggered on [payment success](/docs/appendix/success-event) in frontend. It is used for [Wordpress payments](#glossary) only. The Javascript code is injected into the browser page by [`paycoinly`](#paycoinly) shortcode. You can use `event.data.payload` directly in the Javascript code to access the [payment payload data](/docs/appendix/success-event). ```php title='Example' add_filter('paycoinly_on_complete', function () { return <<` | Your custom HTML to render inside the button | | class | Empty string | Your custom class name to render the button with | | style | Empty string | Your custom style to render the button with | ##### Success handler and redirection By default, the Paycoinly UI launches the payment UI in a popup when triggered, and the Javascript snippet specified by [`paycoinly_on_complete`](#paycoinly_on_complete) filter is executed on [payment completion](/docs/appendix/success-event) if you are subscribed to the **Premium** plan. However, if the `redirect` argument is provided, the payment flow is handled via a full-page redirect instead. Upon successful completion of the payment, the user is then redirected to the URL specified in the `redirect` argument. The Javascript snippet specified by [`paycoinly_on_complete`](#paycoinly_on_complete) filter is ignored in this case. ##### Price Determination You need to decide price from `order_id` by hooking into [`paycoinly_order_price`](#paycoinly_order_price) filter. :::tip[Security Tip] It is not safe to use `order_id` as direct price data when calling the shortcode, since a malicious user could manipulate it to pass any arbitrary amount. To ensure the integrity of your payments, always pass the order ID (or service ID) from the shortcode, and have your backend determine the correct price for that order by using the [`paycoinly_order_price`](#paycoinly_order_price) filter. ::: You can see an example usage in the below. ```php [paycoinly order_id="premium" class="wp-element-button" redirect="/thank-you" html="Pay in Paycoinly"] ``` :::info The shortcode args should be called in one line. ::: ### Best practices [This section](/docs/best-practices/wordpress-plugin-actions-and-filters) also describes best practices for hooking into the above actions and filters.