# 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**

### 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**

### 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.

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**

### 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.

---
## 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**

### 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**

### Configure Woocommerce options
Navigate to **Payments** > **Settings** > **Integration**, select **WordPress or WooCommerce**, and enter the domain of your Woocommerce store.

### Install and configure Paycoinly plugin
- Install Paycoinly plugin in your Wordpress admin dashboard.

- Navigate to Paycoinly in Woocommerce Payments page.

- 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.

#### Anonymous payment
Please set **How would you like to receive customer information?** to **Okay Not To Have Payer Information** in **Payments** > **Settings** > **Basic**.

### Install and configure Paycoinly plugin
- Install Paycoinly plugin in your Wordpress admin dashboard.

- Navigate to Paycoinly in Wordpress admin dashboard.

- 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.

### 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.

:::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.