# API overview
Source: https://docs.zenobank.io/api-reference/api-overview
Quick guide to integrate crypto payments
## Authentication
Send your API key in the `X-API-Key` header:
```
X-API-Key: sk_your_store_key
```
## Integration Steps
### 1. Get your API key
1. Sign in to the [dashboard](https://dashboard.zenobank.io/)
2. Go to **[Developers](https://dashboard.zenobank.io/developer)**
3. Copy your API key (starts with `sk_`)
### 2. Set up webhooks
In the [dashboard](https://dashboard.zenobank.io/), go to **[Developers](https://dashboard.zenobank.io/developer)**, create a webhook endpoint and choose the events you want to subscribe to. See [Webhooks](/api-reference/webhooks) for more details.
### 3. Create a checkout
Use the [Create Checkout](/api-reference/checkouts/create-a-new-checkout) endpoint to generate a payment link for your customer.
### 4. Check checkout status
You can query the current status anytime using [Get Checkout by ID](/api-reference/checkouts/get-checkout-by-id).
***
# Create a checkout
Source: https://docs.zenobank.io/api-reference/checkouts/create-a-new-checkout
Start a new payment session for an order
Create a checkout to generate a hosted payment page for your customer.
## Authentication
Send your store key in the header: `X-API-Key: sk_...`. See the [API overview](/api-reference/api-overview) for where to find it.
## Request body
* `orderId` (string, required): Your internal order identifier.
* `priceAmount` (string, required): Decimal amount, quoted in `priceCurrency`.
* `priceCurrency` (string, required): ISO 4217 currency (e.g., `USD`).
* `successRedirectUrl` (string, optional): Where to send the buyer after a successful payment.
## Example request
```bash theme={null}
curl -X POST https://api.zenobank.io/api/v1/checkouts \
-H "Content-Type: application/json" \
-H "X-API-Key: sk_your_store_key" \
-d '{
"orderId": "order-12345",
"priceAmount": "0.01",
"priceCurrency": "USD",
"successRedirectUrl": "https://example.com/success"
}'
```
```javascript theme={null}
const response = await fetch('https://api.zenobank.io/api/v1/checkouts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'sk_your_store_key',
},
body: JSON.stringify({
orderId: 'order-12345',
priceAmount: '0.01',
priceCurrency: 'USD',
successRedirectUrl: 'https://example.com/success',
}),
});
const checkout = await response.json();
```
```python theme={null}
import requests
response = requests.post(
'https://api.zenobank.io/api/v1/checkouts',
headers={
'Content-Type': 'application/json',
'X-API-Key': 'sk_your_store_key',
},
json={
'orderId': 'order-12345',
'priceAmount': '0.01',
'priceCurrency': 'USD',
'successRedirectUrl': 'https://example.com/success',
},
)
checkout = response.json()
```
```php theme={null}
$ch = curl_init('https://api.zenobank.io/api/v1/checkouts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: sk_your_store_key',
],
CURLOPT_POSTFIELDS => json_encode([
'orderId' => 'order-12345',
'priceAmount' => '0.01',
'priceCurrency' => 'USD',
'successRedirectUrl' => 'https://example.com/success',
]),
]);
$response = curl_exec($ch);
$checkout = json_decode($response, true);
```
```go theme={null}
payload := map[string]string{
"orderId": "order-12345",
"priceAmount": "0.01",
"priceCurrency": "USD",
"successRedirectUrl": "https://example.com/success",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.zenobank.io/api/v1/checkouts", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "sk_your_store_key")
resp, _ := http.DefaultClient.Do(req)
```
```ruby theme={null}
require 'net/http'
require 'json'
uri = URI('https://api.zenobank.io/api/v1/checkouts')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['X-API-Key'] = 'sk_your_store_key'
request.body = {
orderId: 'order-12345',
priceAmount: '0.01',
priceCurrency: 'USD',
successRedirectUrl: 'https://example.com/success'
}.to_json
response = http.request(request)
checkout = JSON.parse(response.body)
```
## Example response
```json theme={null}
{
"id": "ch_l0k1o87yt6",
"orderId": "order-12345",
"priceCurrency": "USD",
"priceAmount": "0.01",
"status": "OPEN",
"expiresAt": "2025-10-04T10:30:00Z",
"checkoutUrl": "https://pay.zenobank.io/ch_l0k1o87yt6",
"createdAt": "2025-10-04T10:00:00Z",
"successRedirectUrl": "https://example.com/success"
}
```
# Get checkout by ID
Source: https://docs.zenobank.io/api-reference/checkouts/get-checkout-by-id
Retrieve the latest state of a checkout
Fetch the current status and payment link for a checkout. This endpoint is public and does not require authentication.
## Path parameters
* `id` (string, required): The checkout ID returned when you created the checkout.
## Example request
```bash theme={null}
curl https://api.zenobank.io/api/v1/public/checkouts/ch_l0k1o87yt6
```
```javascript theme={null}
const response = await fetch('https://api.zenobank.io/api/v1/public/checkouts/ch_l0k1o87yt6');
const checkout = await response.json();
```
```python theme={null}
import requests
response = requests.get('https://api.zenobank.io/api/v1/public/checkouts/ch_l0k1o87yt6')
checkout = response.json()
```
```php theme={null}
$response = file_get_contents('https://api.zenobank.io/api/v1/public/checkouts/ch_l0k1o87yt6');
$checkout = json_decode($response, true);
```
```go theme={null}
resp, _ := http.Get("https://api.zenobank.io/api/v1/public/checkouts/ch_l0k1o87yt6")
defer resp.Body.Close()
var checkout map[string]interface{}
json.NewDecoder(resp.Body).Decode(&checkout)
```
```ruby theme={null}
require 'net/http'
require 'json'
uri = URI('https://api.zenobank.io/api/v1/public/checkouts/ch_l0k1o87yt6')
response = Net::HTTP.get_response(uri)
checkout = JSON.parse(response.body)
```
## Example response
```json theme={null}
{
"id": "ch_l0k1o87yt6",
"orderId": "order-12345",
"priceCurrency": "USD",
"priceAmount": "0.01",
"status": "OPEN",
"expiresAt": "2025-10-04T10:30:00Z",
"checkoutUrl": "https://pay.zenobank.io/ch_l0k1o87yt6",
"createdAt": "2025-10-04T10:00:00Z",
"successRedirectUrl": "https://example.com/success"
}
```
# Webhooks
Source: https://docs.zenobank.io/api-reference/webhooks
Receive checkout lifecycle events
You can manage your webhook endpoints from the **[Webhook section](https://dashboard.zenobank.io/developer)** in the dashboard.
## Setting up endpoints
1. Go to the **[Webhook section](https://dashboard.zenobank.io/developer)** in your store's dashboard.
2. Add an endpoint URL (e.g. `https://example.com/webhooks/zenobank`).
3. Select the event types you want to receive.
## Events
| Event | Description |
| ------------------------- | --------------------------------------------------------------------------------------- |
| `checkout.completed` | The full amount has been paid successfully. |
| `checkout.expired` | The checkout expired without receiving any payment. |
| `checkout.partially_paid` | The checkout expired after receiving a partial payment (`paidAmount` \< `priceAmount`). |
## Payload format
The customer paid the full amount. `paidAmount` is equal to or greater than `priceAmount`.
```json theme={null}
{
"type": "checkout.completed",
"data": {
"id": "ch_l0k1o87yt6",
"orderId": "order-12345",
"priceCurrency": "USD",
"priceAmount": "100.00",
"paidAmount": "100.00",
"status": "COMPLETED",
"expiresAt": "2025-10-05T12:00:00Z",
"checkoutUrl": "https://pay.zenobank.io/ch_l0k1o87yt6",
"createdAt": "2025-10-04T10:00:00Z",
"successRedirectUrl": "https://example.com/success"
}
}
```
No payment was received before the checkout expired. `paidAmount` is `"0"`.
```json theme={null}
{
"type": "checkout.expired",
"data": {
"id": "ch_9xR3mPq2vW",
"orderId": "order-67890",
"priceCurrency": "USD",
"priceAmount": "50.00",
"paidAmount": "0",
"status": "EXPIRED",
"expiresAt": "2025-10-05T12:00:00Z",
"checkoutUrl": "https://pay.zenobank.io/ch_9xR3mPq2vW",
"createdAt": "2025-10-04T10:00:00Z",
"successRedirectUrl": null
}
}
```
The checkout expired after receiving a partial payment. `paidAmount` is greater than `"0"` but less than `priceAmount`. The collected funds will be credited to your store balance.
```json theme={null}
{
"type": "checkout.partially_paid",
"data": {
"id": "ch_4kT7nWx8pQ",
"orderId": "order-11223",
"priceCurrency": "USD",
"priceAmount": "100.00",
"paidAmount": "45.50",
"status": "PARTIALLY_PAID",
"expiresAt": "2025-10-05T12:00:00Z",
"checkoutUrl": "https://pay.zenobank.io/ch_4kT7nWx8pQ",
"createdAt": "2025-10-04T10:00:00Z",
"successRedirectUrl": null
}
}
```
## Verifying webhooks
Every webhook request includes three headers used for signature verification:
| Header | Description |
| ---------------- | ----------------------------- |
| `svix-id` | Unique message identifier |
| `svix-timestamp` | Unix timestamp of the message |
| `svix-signature` | HMAC signature |
Use the official Svix library to verify signatures. To find your signing secret, go to **[Developers](https://dashboard.zenobank.io/developer)**, click on a webhook endpoint, and copy the **Signing Secret** on the right side. It starts with `whsec_`.
### Install the Svix library
`bash pnpm add svix `
`bash pip install svix `
`bash composer require svix/svix `
`bash go get github.com/svix/svix-webhooks/go `
`bash gem install svix `
### Verify the signature
You must use the **raw request body** when verifying webhooks. The
cryptographic signature is sensitive to even the slightest changes. Watch out
for frameworks that parse the request as JSON and then stringify it, as this
will break the signature verification.
```javascript theme={null}
import { Webhook } from 'svix';
const secret = process.env.ZENO_WEBHOOK_SECRET; // whsec_...
const payload = rawBody; // raw request body as string
const headers = {
'svix-id': request.headers.get('svix-id'),
'svix-timestamp': request.headers.get('svix-timestamp'),
'svix-signature': request.headers.get('svix-signature'),
};
const wh = new Webhook(secret);
try {
const msg = wh.verify(payload, headers);
const { type, data } = msg;
switch (type) {
case 'checkout.completed':
// Payment successful — fulfill the order
console.log(`Order ${data.orderId} completed. Paid: ${data.paidAmount} ${data.priceCurrency}`);
break;
case 'checkout.expired':
// Checkout expired — no payment was received
console.log(`Order ${data.orderId} expired`);
break;
case 'checkout.partially_paid':
// Partial payment received — consider issuing a refund
console.log(`Order ${data.orderId} partially paid: ${data.paidAmount}/${data.priceAmount} ${data.priceCurrency}`);
break;
}
} catch (err) {
// Signature verification failed
console.error('Invalid webhook signature');
}
```
```python theme={null}
from svix.webhooks import Webhook, WebhookVerificationError
import os
secret = os.environ.get('ZENO_WEBHOOK_SECRET') # whsec_...
payload = raw_body # raw request body, not parsed JSON
headers = request_headers
wh = Webhook(secret)
try:
msg = wh.verify(payload, headers)
except WebhookVerificationError:
# Signature verification failed
raise Exception('Invalid webhook signature')
event_type = msg['type']
if event_type == 'checkout.completed':
# Payment successful — fulfill the order
print(f"Order {msg['data']['orderId']} completed. Paid: {msg['data']['paidAmount']} {msg['data']['priceCurrency']}")
elif event_type == 'checkout.expired':
# Checkout expired — no payment was received
print(f"Order {msg['data']['orderId']} expired")
elif event_type == 'checkout.partially_paid':
# Partial payment received — consider issuing a refund
print(f"Order {msg['data']['orderId']} partially paid: {msg['data']['paidAmount']}/{msg['data']['priceAmount']} {msg['data']['priceCurrency']}")
```
```php theme={null}
use Svix\Webhook;
use Svix\Exception\WebhookVerificationException;
$secret = getenv('ZENO_WEBHOOK_SECRET'); // whsec_...
$payload = file_get_contents('php://input'); // raw body
$headers = array_change_key_case(getallheaders(), CASE_LOWER);
try {
$wh = new Webhook($secret);
$msg = $wh->verify($payload, $headers);
switch ($msg['type']) {
case 'checkout.completed':
// Payment successful — fulfill the order
fulfillOrder($msg['data']['orderId']);
break;
case 'checkout.expired':
// Checkout expired — no payment was received
handleExpiredCheckout($msg['data']['orderId']);
break;
case 'checkout.partially_paid':
// Partial payment received — consider issuing a refund
handlePartialPayment($msg['data']['orderId'], $msg['data']['paidAmount']);
break;
}
http_response_code(200);
} catch (WebhookVerificationException $e) {
// Signature verification failed
http_response_code(400);
}
```
```go theme={null}
import (
"encoding/json"
"io"
"net/http"
"os"
svix "github.com/svix/svix-webhooks/go"
)
secret := os.Getenv("ZENO_WEBHOOK_SECRET") // whsec_...
payload, _ := io.ReadAll(r.Body) // raw body
wh, _ := svix.NewWebhook(secret)
err := wh.Verify(payload, r.Header)
if err != nil {
// Signature verification failed
w.WriteHeader(http.StatusBadRequest)
return
}
var event struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}
json.Unmarshal(payload, &event)
switch event.Type {
case "checkout.completed":
// Payment successful — fulfill the order
case "checkout.expired":
// Checkout expired — no payment was received
case "checkout.partially_paid":
// Partial payment received — consider issuing a refund
}
w.WriteHeader(http.StatusOK)
```
```ruby theme={null}
require 'svix'
require 'json'
secret = ENV['ZENO_WEBHOOK_SECRET'] # whsec_...
payload = raw_body # raw request body
headers = request_headers
wh = Svix::Webhook.new(secret)
begin
msg = wh.verify(payload, headers)
case msg['type']
when 'checkout.completed'
# Payment successful — fulfill the order
puts "Order #{msg['data']['orderId']} completed. Paid: #{msg['data']['paidAmount']} #{msg['data']['priceCurrency']}"
when 'checkout.expired'
# Checkout expired — no payment was received
puts "Order #{msg['data']['orderId']} expired"
when 'checkout.partially_paid'
# Partial payment received — consider issuing a refund
puts "Order #{msg['data']['orderId']} partially paid: #{msg['data']['paidAmount']}/#{msg['data']['priceAmount']} #{msg['data']['priceCurrency']}"
end
rescue
# Signature verification failed
puts 'Invalid webhook signature'
end
```
Always verify the signature before processing the event. Never trust the
payload without verification. You must use the **raw request body**, do not
parse the JSON before verifying.
For framework-specific examples (Express, Next.js, Django, Flask, Laravel, Rails, etc.), see the Svix verification docs.
## FAQ
If Zeno Bank does not receive a `2xx` response from your webhook endpoint, we will retry the delivery.
Each message is attempted based on the following schedule, where each period starts after the failure of the preceding attempt:
* 5 seconds
* 5 minutes
* 30 minutes
* 2 hours
* 5 hours
* 10 hours
Respond with any `2xx` status code to acknowledge the event. You can monitor delivery attempts and manually retry from the **[Developers](https://dashboard.zenobank.io/developer)** section in the dashboard.
Zeno Bank webhooks provide **at-least-once** delivery. Every event will be delivered to your endpoint at least once, but may be delivered more than once in rare cases (such as network timeouts where your server processed the event but the acknowledgement was lost).
To handle duplicates, use the `svix-id` header included with every webhook request. This is a unique identifier for each event delivery. Store processed `svix-id` values and skip any duplicates.
Yes. Go to **[Developers](https://dashboard.zenobank.io/developer)** in the
dashboard, click on your webhook endpoint, find the event you want to retry,
and click the replay button to resend it.
No. If you use one of our official plugins (WooCommerce, PrestaShop, WHMCS, etc.), webhooks are configured automatically. You don't need to set up endpoints or verify signatures manually.
## IP allowlist
If your firewall is blocking our webhooks, add these IP addresses to your allowlist.
```
44.228.126.217
50.112.21.217
52.24.126.164
54.148.139.208
2600:1f24:64:8000::/56
```
# Brand Assets
Source: https://docs.zenobank.io/brand-assets
Official Zeno Bank logos and brand resources for partners and integrators.
## Wordmark
Black wordmark
White wordmark
| Format | Light background | Dark background |
| ------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| PNG | zenobank-text-light.png | zenobank-text-dark.png |
## Icon
Light background
Dark background
| Format | Light background | Dark background |
| ------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| PNG | zenobank-icon-light.png | zenobank-icon-dark.png |
## Favicon
Favicon
| Format | File |
| ------ | -------------------------------------- |
| PNG | favicon.png |
| ICO | favicon.ico |
## Typeface
Black typeface (SVG)
White typeface (SVG)
| Format | Light background | Dark background |
| ------ | ----------------------------------------------------------------- | ----------------------------------------------------------------- |
| SVG | typeface-black.svg | typeface-white.svg |
| PNG | typeface-black.png | typeface-white.png |
## Checkout Logos
If you are integrating via the API, you can use these logos to display Zeno as a payment method at checkout.
## Colors
| Color | Hex | RGB | CMYK | Pantone |
| ----------------- | --------- | ------------- | -------------- | ------------------ |
| **Black** | `#000000` | 0, 0, 0 | 75, 68, 67, 90 | Black 6 C / 4147 U |
| **White** | `#FFFFFF` | 255, 255, 255 | 0, 0, 0, 0 | — |
# Fees
Source: https://docs.zenobank.io/fees
A transparent breakdown of Zeno's payment processing fees.
## Crypto Payment Fees
### Base Fee
We charge a **0.1% fee** on each payment. The fee is deducted after each sweep , when funds are moved from the intermediary wallet to you, we send you 99.9% of the amount and keep 0.1%.
### Network Fees
In addition to the base fee, **network fees apply when sweeping funds** from the intermediary wallet to your destination wallet.
On most chains, these fees are so small they are practically imperceptible. However, on networks like Tron, fees can be notably higher.
### Binance Pay
Binance Pay transactions have a **0% fee**. Funds are received directly into your Binance account with no intermediaries involved. Charging a fee here would unnecessarily complicate our fee structure, so we simply don't.
### Lightning Network
Payments over the Lightning Network carry a **0.35% fee** instead of the standard 0.1%. This higher rate is necessary to cover the cost of managing Lightning Network liquidity, which requires significant operational effort.
## Withdrawals
The fee for each withdrawal is **\$1 + network fees**.
If you use **bring your own wallet mode**, funds are received directly in your wallet, so no withdrawal fee applies.
# Quick Start
Source: https://docs.zenobank.io/index
Accept crypto payments with 0.1% fees, instant payouts, and no chargebacks.
Zeno Bank is a payment gateway that lets you accept **crypto payments with very low fees**. We're not here to replace your existing payment gateway. We're here to **complement it**.
We **abstract the complexity of crypto** so you can enjoy its benefits without worrying about the technical details.
## Why Accept Crypto?
### No More Frozen Accounts
You built your business from scratch. Late nights, sacrifices, **years of hard work**. Then one morning, **your payment gateway freezes your account** for suspicious activity. Now **you can't process any more payments**, but your bills don't stop. There's nothing you can do about it but wait for a reply to your appeal
### Lower Fees
Traditional gateways charge 3% on average, sometimes up to 10%. We charge just **0.1%**. That's **30x less**.
Imagine reinvesting that 3% back into your business. **The compound effect over 5 years would be massive.** It's like going to the gym. You don't see results right away, but they add up.
### Reach Global Customers
Millions of people in Latin America and Africa use apps like Binance to protect their savings in USDT from hyperinflation. **Most of them don't even know they're using crypto.** They just know their money holds its value because 1 USDT = 1 USD. By accepting crypto, you **unlock access to this massive market** of customers who are already spending in stablecoins every day but can't reach you through traditional payment methods.
### No More Fraud
Fraudulent returns cost US retailers [**\$76.5 billion a year**](https://www.forbes.com/sites/pamdanziger/2026/02/16/fraud-is-only-the-tip-of-retails-850-billion-returns-challenge/) according to Forbes. Amazon had to cut back its return program because people kept abusing it.
The same happens to you. A customer opens a PayPal dispute, and **PayPal always sides with the customer**. Too many disputes? They close your account.
With crypto, **payments are final**. You're in control. You decide whether to issue a refund or not
### Get Paid Immediately
No more waiting days or weeks. **You get paid in minutes.** Reinvest in ads, pay suppliers, move faster. Old payment rails no longer slow you down.
## Big Players Are Already Using Crypto
**PayPal, Revolut, and many more** are already processing payments through crypto. The biggest companies in fintech are betting on it. The question is: why aren't you?
## The Future Is Already Here
Stablecoin adoption is **growing rapidly year over year**. The only reason not to accept crypto is if you want to fall behind.
## Supported Platforms
<> >
<> >
<> >
<> >
<> >
# Binance Pay
Source: https://docs.zenobank.io/integrations/binance-pay
Connect your Binance account to accept Binance Pay payments
With the Binance Pay integration, you can let your **customers** pay using **Binance Pay** in just a few clicks.
ZenoBank works as a payment processor that validates each transaction using your Binance Pay payment history via API.
**Funds** sent by customers **go directly to your Binance account**.
You **don't need** to have a **merchant Binance account**. You can use your regular Binance account.
## Step 1: Locate Your Binance ID
1. Log in to your Binance account at [binance.com](https://binance.com)
2. Navigate to your dashboard
3. Locate your **Binance ID** in the dashboard interface
4. Copy and securely store your Binance ID—you will need it later in the integration process
## Step 2: Access API Management
1. In your Binance account, click on the **Account** dropdown menu
2. Select **API Management** from the dropdown options
## Step 3: Create API Key
1. Click the **Create API** button to begin the API key creation process
## Step 4: Select API Key Type
1. You will be prompted to choose between **System generated** and **Self-generated**
2. Select **System generated**
3. Click **Next** to proceed
## Step 5: Name Your API Key
1. Enter a name for your API key (e.g., "zeno bank")
2. This name is for identification purposes only and does not affect functionality
3. Click **Next** to continue
## Step 6: Configure API Permissions
Ensure that **only the Read permission is enabled**.
This restriction is critical for security. With read-only access, ZenoBank can only read your Binance Pay payment history
## Step 7: Copy Your Credentials
After creating your API key, Binance will display:
* **API Key**
* **API Secret**
## Step 8: Configure Integration in ZenoBank Dashboard
1. Log in to your [ZenoBank dashboard](https://dashboard.zenobank.io)
2. Navigate to **[Settings](https://dashboard.zenobank.io/settings)** in the sidebar menu
3. Click **Connect Binance Pay**
## Step 9: Enter Your Credentials
1. A modal dialog will open prompting you to enter your Binance credentials
2. Enter the following information:
* **Binance ID** (from Step 1)
* **API Key** (from Step 7)
* **API Secret** (from Step 7)
3. Click **Save** to complete the integration
# Easy Digital Downloads
Source: https://docs.zenobank.io/integrations/easy-digital-downloads
Accept crypto payments on your Easy Digital Downloads store
This guide walks you through installing and configuring the **ZenoBank Payment Gateway** plugin on your Easy Digital Downloads store.
Before you begin, make sure **[Easy Digital Downloads](https://wordpress.org/plugins/easy-digital-downloads/) is already installed and active** on your WordPress site.
## Step 1: Install the Zeno Bank Plugin
1. Log in to your WordPress admin dashboard.
2. Go to **Plugins → Add New**.
3. Search for **"Zeno Crypto Checkout for Easy Digital Downloads"**.
4. Click **Install Now**, then click **Activate**.
View plugin on WordPress.org
## Step 2: Enable Automatic Updates (Optional)
1. Click **Enable auto-updates** so you always have the latest version.
## Step 3: Get Your API Key
1. Visit the **ZenoBank Dashboard**: [https://dashboard.zenobank.io](https://dashboard.zenobank.io)
2. Navigate to **[Developers](https://dashboard.zenobank.io/developer)**.
3. Copy the generated **API Key**.
## Step 4: Open Plugin Settings
1. In your WordPress admin dashboard, go to **Downloads → Settings**.
2. Click on the **Payment Gateways** tab.
3. Find **ZenoBank - Crypto Payments** in the list.
## Step 5: Configure The Gateway
1. Make sure the **ZenoBank - Crypto Payments** checkbox is checked to enable it.
2. Click on **ZenoBank - Crypto Payments** to expand the settings.
3. Paste your **API Key** from the ZenoBank dashboard into the API Key field.
4. Click **Save Changes**.
# MemberPress
Source: https://docs.zenobank.io/integrations/memberpress
Accept crypto payments on your MemberPress membership site
This guide walks you through installing and configuring the **ZenoBank Payment Gateway** plugin on your MemberPress membership site.
Before you begin, make sure **[MemberPress](https://memberpress.com/) is already installed and active** on your WordPress site.
## Step 1: Install the Zeno Bank Plugin
1. Log in to your WordPress admin dashboard.
2. Go to **Plugins → Add New**.
3. Search for **"Zeno Crypto Checkout for MemberPress"**.
4. Click **Install Now**, then click **Activate**.
View plugin on WordPress.org
## Step 2: Enable Automatic Updates (Optional)
1. Click **Enable auto-updates** so you always have the latest version.
## Step 3: Get Your API Key
1. Visit the **ZenoBank Dashboard**: [https://dashboard.zenobank.io](https://dashboard.zenobank.io)
2. Navigate to **[Developers](https://dashboard.zenobank.io/developer)**.
3. Copy the generated **API Key**.
## Step 4: Open Plugin Settings
1. In your WordPress admin dashboard, go to **MemberPress → Settings**.
2. Click on the **Payments** tab.
3. Click **Add Payment Method**.
4. Select **ZenoBank - Crypto Payments** from the gateway dropdown.
## Step 5: Configure The Gateway
1. Paste your **API Key** from the ZenoBank dashboard into the API Key field.
2. (Optional) Customize the **Name** that customers will see at checkout.
3. Click **Update Options** to save your changes.
# PrestaShop
Source: https://docs.zenobank.io/integrations/prestashop
Accept crypto payments on your PrestaShop store
This guide walks you through installing and configuring the **ZenoBank Payment Gateway** module on your PrestaShop store.
## Step 1: Download the Module
1. Download the **Zeno Crypto Payment Gateway** module from [here](https://zenobank.io/downloads/prestashop/latest).
## Step 2: Install the Module
1. Log in to your **PrestaShop Back Office**.
2. Go to **Modules → Module Manager**.
3. Click **Upload a module** in the top right corner.
4. Drag and drop the `.zip` file or click to select it.
5. Wait for the installation to complete.
## Step 3: Get Your API Key
1. Visit the **ZenoBank Dashboard**: [https://dashboard.zenobank.io](https://dashboard.zenobank.io)
2. Navigate to **[Developers](https://dashboard.zenobank.io/developer)**.
3. Copy the generated **API Key**.
## Step 4: Configure the Module
1. After installation, click **Configure** on the module card.
* You can also find it by going to **Modules → Module Manager** and searching for **"ZenoBank"**.
2. Paste your **API Key** from the ZenoBank dashboard into the API Key field.
3. Click **Save**.
# WHMCS
Source: https://docs.zenobank.io/integrations/whmcs
Accept crypto payments on your WHMCS platform
This guide walks you through installing and configuring the **ZenoBank Payment Gateway** module on your WHMCS platform.
## Step 1: Download the Module
1. Download the **ZenoBank Payment Gateway** module from the [WHMCS Marketplace](https://marketplace.whmcs.com/product/8461-zeno-crypto-gateway?utm_source=docs\&utm_medium=integration_guide\&utm_campaign=whmcs).
## Step 2: Upload the Module Files
1. Extract the downloaded `.zip` file.
2. Upload the module files to your WHMCS installation directory:
* Copy the gateway file to `/modules/gateways/`
* Copy the callback file to `/modules/gateways/callback/`
You can upload the files using FTP, SFTP, or your hosting provider's file manager.
## Step 3: Get Your API Key
1. Visit the **ZenoBank Dashboard**: [https://dashboard.zenobank.io](https://dashboard.zenobank.io)
2. Navigate to **[Developers](https://dashboard.zenobank.io/developer)**.
3. Copy the generated **API Key**.
## Step 4: Activate the Payment Gateway
1. Log in to your **WHMCS Admin Area**.
2. Go to **Setup → Payments → Payment Gateways**.
3. Click the **All Payment Gateways** tab.
4. Find **ZenoBank - Crypto Payments** and click **Activate**.
## Step 5: Configure the Gateway
1. After activation, the configuration form will appear.
2. Paste your **API Key** from the ZenoBank dashboard into the API Key field.
3. Click **Save Changes**.
# Wix
Source: https://docs.zenobank.io/integrations/wix
Accept crypto payments on your Wix store with a custom Zeno Bank payment provider.
Register this webhook URL in the [Zeno Bank Dashboard](https://dashboard.zenobank.io/developer):
```
https:///_functions/updateZenoBankTransaction
```
Example: `https://zenobank.io/_functions/updateZenoBankTransaction`
```
https://.wixsite.com//_functions/updateZenoBankTransaction
```
Example: `https://zenobankio.wixsite.com/my-site-2/_functions/updateZenoBankTransaction`
***
This is the code you need to copy:
```javascript zeno-bank-config.js theme={null}
import * as paymentProvider from 'interfaces-psp-v1-payment-service-provider';
// ─────────────────────────────────────────────────────────────
// CUSTOMIZE HERE (optional)
// Edit these values to change how your payment method appears
// on the dashboard and at checkout.
// ─────────────────────────────────────────────────────────────
const PAYMENT_METHOD_TITLE = 'Pay with Crypto';
const LOGOS = {
white: {
svg: 'https://cryptologos.zenobank.io/library/tether-icon-dark.svg',
png: 'https://cryptologos.zenobank.io/library/tether-icon-dark.png',
},
colored: {
svg: 'https://cryptologos.zenobank.io/library/tether-icon-light.png',
png: 'https://cryptologos.zenobank.io/library/tether-icon-light.svg',
},
};
// ─────────────────────────────────────────────────────────────
/** @returns {import('interfaces-psp-v1-payment-service-provider').PaymentServiceProviderConfig} */
export function getConfig() {
return {
title: 'Zeno Bank',
paymentMethods: [{
hostedPage: {
title: PAYMENT_METHOD_TITLE,
billingAddressMandatoryFields: [],
logos: LOGOS,
},
}],
credentialsFields: [
{
simpleField: { name: 'apiKey', label: 'Zeno API Key' },
},
{
simpleField: { name: 'webhookSecret', label: 'Webhook Signing Secret (whsec_...)' },
},
],
};
}
```
```javascript zeno-bank.js theme={null}
import * as paymentProvider from 'interfaces-psp-v1-payment-service-provider';
import { secrets } from 'wix-secrets-backend.v2';
import { elevate } from 'wix-auth';
const ZENO_WEBHOOK_SECRET_NAME = 'ZENO_WEBHOOK_SECRET';
const listSecretInfoElevated = elevate(secrets.listSecretInfo);
const createSecretElevated = elevate(secrets.createSecret);
const updateSecretElevated = elevate(secrets.updateSecret);
/**
* @param {import('interfaces-psp-v1-payment-service-provider').ConnectAccountOptions} options
* @param {import('interfaces-psp-v1-payment-service-provider').Context} context
* @returns {Promise}
*/
export const connectAccount = async (options, context) => {
const { apiKey, webhookSecret } = options.credentials;
if (!webhookSecret) {
return {
reasonCode: 2009,
errorCode: 'INVALID_CREDENTIALS',
errorMessage: 'Webhook signing secret is required',
};
}
const list = await listSecretInfoElevated();
const existing = list.secrets.find((s) => s.name === ZENO_WEBHOOK_SECRET_NAME);
const payload = { name: ZENO_WEBHOOK_SECRET_NAME, value: webhookSecret };
if (existing) {
await updateSecretElevated(existing._id, payload);
} else {
await createSecretElevated(payload);
}
return {
credentials: { apiKey },
accountId: 'zenobank',
accountName: 'Zeno Bank',
};
};
function minorToMajor(amount, currency) {
const fractionDigits = new Intl.NumberFormat('en', {
style: 'currency',
currency,
}).resolvedOptions().maximumFractionDigits;
if (fractionDigits === undefined || fractionDigits === null) {
throw new Error(`Fraction digits not found for currency ${currency}`);
}
return +amount / Math.pow(10, fractionDigits);
}
/**
* @param {import('interfaces-psp-v1-payment-service-provider').CreateTransactionOptions} options
* @param {import('interfaces-psp-v1-payment-service-provider').Context} context
* @returns {Promise}
*/
export const createTransaction = async (options, context) => {
const { totalAmount, currency } = options.order.description;
const { successUrl } = options.order.returnUrls;
const request = await fetch('https://api.zenobank.io/api/v1/checkouts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': options.merchantCredentials.apiKey,
},
body: JSON.stringify({
orderId: options.wixTransactionId,
priceAmount: minorToMajor(totalAmount, currency),
priceCurrency: currency,
successRedirectUrl: successUrl,
}),
});
const response = await request.json();
return {
pluginTransactionId: response.id,
redirectUrl: response.checkoutUrl,
};
};
/**
* @param {import('interfaces-psp-v1-payment-service-provider').RefundTransactionOptions} options
* @param {import('interfaces-psp-v1-payment-service-provider').Context} context
* @returns {Promise}
*/
export const refundTransaction = async (options, context) => {
return {
pluginRefundId: Math.random().toString(36).slice(2) + Date.now().toString(36),
reasonCode: 3022,
errorCode: 'REFUND_NOT_ALLOWED',
errorMessage: 'Refund not allowed',
};
};
```
```javascript http-functions.js theme={null}
import wixPaymentProviderBackend from "wix-payment-provider-backend";
import { secrets } from "wix-secrets-backend.v2";
import { elevate } from "wix-auth";
import { ok, forbidden, badRequest, serverError } from "wix-http-functions";
import crypto from "crypto";
const TOLERANCE_SECONDS = 5 * 60;
const ZENO_WEBHOOK_SECRET_NAME = "ZENO_WEBHOOK_SECRET";
const getSecretValueElevated = elevate(secrets.getSecretValue);
function readHeader(headers, primary, fallback) {
return headers[primary] ?? headers[fallback] ?? null;
}
async function verifyZenoWebhook(request) {
const rawBody = await request.body.text();
const webhookId = readHeader(request.headers, "svix-id", "zeno-id");
const webhookTimestamp = readHeader(request.headers, "svix-timestamp", "zeno-timestamp");
const webhookSignature = readHeader(request.headers, "svix-signature", "zeno-signature");
if (!webhookId || !webhookTimestamp || !webhookSignature) return null;
const ts = parseInt(webhookTimestamp, 10);
const now = Math.floor(Date.now() / 1000);
if (isNaN(ts) || Math.abs(now - ts) > TOLERANCE_SECONDS) return null;
const { value } = await getSecretValueElevated(ZENO_WEBHOOK_SECRET_NAME);
let secret = value;
if (secret.startsWith("whsec_")) secret = secret.slice(6);
const keyBytes = Buffer.from(secret, "base64");
const signedContent = `${webhookId}.${webhookTimestamp}.${rawBody}`;
const expectedSig = crypto
.createHmac("sha256", keyBytes)
.update(signedContent)
.digest("base64");
const expectedBuf = Buffer.from(expectedSig);
for (const versioned of webhookSignature.split(" ")) {
const [version, sig] = versioned.split(",");
if (version !== "v1" || !sig) continue;
const receivedBuf = Buffer.from(sig);
if (
receivedBuf.length === expectedBuf.length &&
crypto.timingSafeEqual(receivedBuf, expectedBuf)
) {
return JSON.parse(rawBody);
}
}
return null;
}
export async function post_updateZenoBankTransaction(request) {
console.log("Zeno webhook received");
const response = { headers: { "Content-Type": "application/json" } };
let event;
try {
event = await verifyZenoWebhook(request);
} catch (err) {
console.error("Verification error:", err);
return serverError(response);
}
if (!event) {
return forbidden({ ...response, body: { error: "Invalid signature" } });
}
if (event.type !== "checkout.completed") {
return ok(response);
}
const wixTransactionId = event.data.orderId;
const pluginTransactionId = event.data.id;
if (!wixTransactionId || !pluginTransactionId) {
return badRequest({ ...response, body: { error: "Missing transaction IDs" } });
}
try {
await wixPaymentProviderBackend.submitEvent({
event: {
transaction: { wixTransactionId, pluginTransactionId },
},
});
} catch (err) {
console.error("submitEvent failed:", err);
return serverError(response);
}
return ok(response);
}
```
# WooCommerce
Source: https://docs.zenobank.io/integrations/woocommerce
Accept crypto payments on your WooCommerce store with the Zeno Bank plugin.
This guide walks you through installing and configuring the **ZenoBank Payment Gateway** plugin on your WooCommerce store.
Before you begin, make sure **[WooCommerce](https://wordpress.org/plugins/woocommerce/) is already installed and active** on your WordPress site.
## Step 1: Install the Zeno Bank Plugin
1. Log in to your WordPress admin dashboard.
2. Go to **Plugins → Add New**.
3. Search for **"Zeno Crypto Payment Gateway"**.
4. Click **Install Now**, then click **Activate**.
View plugin on WordPress.org
## Step 2: Enable Automatic Updates (Optional)
1. Click **Enable auto-updates** so you always have the latest version.
## Step 3: Get Your API Key
1. Visit the **ZenoBank Dashboard**: [https://dashboard.zenobank.io](https://dashboard.zenobank.io)
2. Navigate to **[Developers](https://dashboard.zenobank.io/developer)**.
3. Copy the generated **API Key**.
## Step 4: Open Plugin Settings
1. In your WordPress admin dashboard, go to **Plugins → Installed Plugins**.
2. Find **Zeno Crypto Payment Gateway**.
3. Click **Settings** to open the plugin settings.
## Step 5: Configure The Gateway
1. Make sure the **Enable ZenoBank Payment Gateway** option is checked.
2. Paste your **API Key** from the ZenoBank dashboard into the API Key field.
3. (Optional) Customize the **Title** that customers will see at checkout.
4. (Optional) Customize the **Description** that customers will see at checkout.
5. Click **Save changes**.
# Payment Flow
Source: https://docs.zenobank.io/payment-flow
How Zeno Bank processes crypto payments using intermediary wallets, sweeps, and webhook notifications.
## Overview
At checkout, users can pay using multiple tokens and networks. We use an **intermediary wallet model**, instead of sending funds directly to your wallet, users send payments to a temporary intermediary wallet that we control. This architecture unlocks several powerful features.
## How It Works
### 1. User Initiates Payment
When a user reaches the checkout, they are presented with a selection of supported tokens and networks. The user sends funds to the intermediary wallet address provided.
### 2. Payment Detection
We monitor the intermediary wallet and detect incoming transactions. Once the full amount is received before the expiration time, we:
* **Sweep the funds** to your Zeno balance or to your non-custodial wallet (depending on the mode you are using).
* **Mark the payment as completed.**
### 3. Expiration Handling
* **Partial payment:** If the user has sent some funds but not the full amount by the expiration time, we mark the payment as **partially paid** and sweep whatever was received to your Zeno balance or your non-custodial wallet (depending on the mode you are using).
* **No payment:** If no funds were received, we mark the payment as **expired**.
## Benefits of the Intermediary Wallet Model
### Wrong Token Detection
If a user chooses to pay with USDC on Ethereum but accidentally sends USDT on Arbitrum, we detect the payment anyway. This happens more often than you think, and it dramatically reduces support tickets.
### Multi-Token Payments
Users can split a payment across multiple tokens and networks. For example, on a 2,000 USD checkout, a user could send 1,000 USDC on Solana, 700 USDT on Ethereum, and \$300 worth of Bitcoin.
This makes bigger purchases easier for your customers, since they don't need all the funds in a single token to complete the payment. Less friction = fewer abandoned checkouts = more sales.
### Less Customer Support
Because we automatically detect mismatched tokens and support multi-token payments, most payment issues are resolved before they even reach us. And if something does go wrong, our support team handles it. You just focus on selling, we handle the rest
## Binance Pay
If you integrate **Binance Pay**, the intermediary wallet model does **not** apply. With Binance Pay:
* The user must send the **exact amount** in a **single transaction**.
* Funds go directly to your Binance account.
## Token & Network Availability
The tokens and networks displayed at checkout are fully **customizable**.
You can enable or disable specific tokens from the [dashboard](https://dashboard.zenobank.io/).
However, we recommend **leaving all tokens and networks enabled**.
Different regions and users have different preferences, for example, Tron is popular across Asia, while other users may hold all their funds on Solana.
**Keeping all options enabled ensures no customer is left without a way to pay.**
## Disabled Tokens on Low Amounts
When the **checkout amount is very small, certain tokens and networks are automatically disabled** if the network fee would exceed the payment amount.
For example, Tron network fees can be relatively high, under the intermediary wallet model, sweeping the funds would cost more than the payment itself. The same logic applies to other high-fee networks.
## Webhooks
You can subscribe to payment events (e.g., `checkout.completed`). For more info, see [webhooks](/api-reference/webhooks).
If you are using a plugin (e.g., the WooCommerce plugin), webhook handling is built in and configured automatically.
# PHP
Source: https://docs.zenobank.io/php-sdk
Official PHP SDK for Zeno Bank
Source and docs on GitHub.
# Supported Fiat Currencies
Source: https://docs.zenobank.io/supported-currencies
Full list of fiat currencies supported by Zeno Bank for pricing checkouts and withdrawals.
| Code | Currency |
| ---- | ----------------------------------- |
| AED | United Arab Emirates Dirham |
| AFN | Afghan Afghani |
| ALL | Albanian Lek |
| AMD | Armenian Dram |
| ANG | Netherlands Antillean Guilder |
| AOA | Angolan Kwanza |
| ARS | Argentine Peso |
| AUD | Australian Dollar |
| AWG | Aruban Florin |
| AZN | Azerbaijani Manat |
| BAM | Bosnia-Herzegovina Convertible Mark |
| BBD | Barbadian Dollar |
| BDT | Bangladeshi Taka |
| BGN | Bulgarian Lev |
| BHD | Bahraini Dinar |
| BIF | Burundian Franc |
| BMD | Bermudan Dollar |
| BND | Brunei Dollar |
| BOB | Bolivian Boliviano |
| BRL | Brazilian Real |
| BSD | Bahamian Dollar |
| BTN | Bhutanese Ngultrum |
| BWP | Botswanan Pula |
| BYN | New Belarusian Ruble |
| BZD | Belize Dollar |
| CAD | Canadian Dollar |
| CDF | Congolese Franc |
| CHF | Swiss Franc |
| CLP | Chilean Peso |
| CNY | Chinese Yuan |
| COP | Colombian Peso |
| CRC | Costa Rican Colón |
| CUP | Cuban Peso |
| CVE | Cape Verdean Escudo |
| CZK | Czech Republic Koruna |
| DJF | Djiboutian Franc |
| DKK | Danish Krone |
| DOP | Dominican Peso |
| DZD | Algerian Dinar |
| EGP | Egyptian Pound |
| ERN | Eritrean Nakfa |
| ETB | Ethiopian Birr |
| EUR | Euro |
| FJD | Fijian Dollar |
| FKP | Falkland Islands Pound |
| GBP | British Pound Sterling |
| GEL | Georgian Lari |
| GGP | Guernsey Pound |
| GHS | Ghanaian Cedi |
| GIP | Gibraltar Pound |
| GMD | Gambian Dalasi |
| GNF | Guinean Franc |
| GTQ | Guatemalan Quetzal |
| GYD | Guyanaese Dollar |
| HKD | Hong Kong Dollar |
| HNL | Honduran Lempira |
| HRK | Croatian Kuna |
| HTG | Haitian Gourde |
| HUF | Hungarian Forint |
| IDR | Indonesian Rupiah |
| ILS | Israeli New Sheqel |
| IMP | Manx pound |
| INR | Indian Rupee |
| IQD | Iraqi Dinar |
| IRR | Iranian Rial |
| ISK | Icelandic Króna |
| JEP | Jersey Pound |
| JMD | Jamaican Dollar |
| JOD | Jordanian Dinar |
| JPY | Japanese Yen |
| KES | Kenyan Shilling |
| KGS | Kyrgystani Som |
| KHR | Cambodian Riel |
| KMF | Comorian Franc |
| KRW | South Korean Won |
| KWD | Kuwaiti Dinar |
| KYD | Cayman Islands Dollar |
| KZT | Kazakhstani Tenge |
| LAK | Laotian Kip |
| LBP | Lebanese Pound |
| LKR | Sri Lankan Rupee |
| LRD | Liberian Dollar |
| LSL | Lesotho Loti |
| LYD | Libyan Dinar |
| MAD | Moroccan Dirham |
| MDL | Moldovan Leu |
| MGA | Malagasy Ariary |
| MKD | Macedonian Denar |
| MMK | Myanma Kyat |
| MNT | Mongolian Tugrik |
| MOP | Macanese Pataca |
| MRU | Mauritanian Ouguiya |
| MUR | Mauritian Rupee |
| MVR | Maldivian Rufiyaa |
| MWK | Malawian Kwacha |
| MXN | Mexican Peso |
| MYR | Malaysian Ringgit |
| MZN | Mozambican Metical |
| NAD | Namibian Dollar |
| NGN | Nigerian Naira |
| NIO | Nicaraguan Córdoba |
| NOK | Norwegian Krone |
| NPR | Nepalese Rupee |
| NZD | New Zealand Dollar |
| OMR | Omani Rial |
| PAB | Panamanian Balboa |
| PEN | Peruvian Nuevo Sol |
| PGK | Papua New Guinean Kina |
| PHP | Philippine Peso |
| PKR | Pakistani Rupee |
| PLN | Polish Zloty |
| PYG | Paraguayan Guarani |
| QAR | Qatari Rial |
| RON | Romanian Leu |
| RSD | Serbian Dinar |
| RUB | Russian Ruble |
| RWF | Rwandan Franc |
| SAR | Saudi Riyal |
| SBD | Solomon Islands Dollar |
| SCR | Seychellois Rupee |
| SDG | South Sudanese Pound |
| SEK | Swedish Krona |
| SGD | Singapore Dollar |
| SHP | Saint Helena Pound |
| SLE | Sierra Leonean Leone |
| SLL | Sierra Leonean Leone |
| SOS | Somali Shilling |
| SRD | Surinamese Dollar |
| STN | São Tomé and Príncipe Dobra |
| SYP | Syrian Pound |
| SZL | Swazi Lilangeni |
| THB | Thai Baht |
| TJS | Tajikistani Somoni |
| TMT | Turkmenistani Manat |
| TND | Tunisian Dinar |
| TOP | Tongan Paʻanga |
| TRY | Turkish Lira |
| TTD | Trinidad and Tobago Dollar |
| TWD | New Taiwan Dollar |
| TZS | Tanzanian Shilling |
| UAH | Ukrainian Hryvnia |
| UGX | Ugandan Shilling |
| USD | United States Dollar |
| UYU | Uruguayan Peso |
| UZS | Uzbekistan Som |
| VES | Sovereign Bolivar |
| VND | Vietnamese Dong |
| VUV | Vanuatu Vatu |
| WST | Samoan Tala |
| XAF | CFA Franc BEAC |
| XCD | East Caribbean Dollar |
| XCG | Caribbean Guilder |
| XOF | CFA Franc BCEAO |
| XPF | CFP Franc |
| YER | Yemeni Rial |
| ZAR | South African Rand |
| ZMW | Zambian Kwacha |
| ZWL | Zimbabwean Dollar |
# Supported Tokens
Source: https://docs.zenobank.io/supported-tokens
Tokens and networks supported by Zeno Bank: USDC, USDT, PYUSD, ETH, BNB, POL, SOL, BTC, and LTC across multiple chains.
## USDC
Supported on: Binance Pay, Ethereum, Arbitrum One, BNB Chain, Polygon, Base, Solana
## USDT
Supported on: Binance Pay, Ethereum, Arbitrum One, BNB Chain, Polygon, Base, Tron
## PYUSD
Supported on: Ethereum, Solana
## ETH
Supported on: Ethereum, Arbitrum One, Base, Polygon, BNB Chain
*Wrapped Ether (WETH) is also supported. On Polygon and BNB Chain, ETH is available exclusively as WETH.*
## BNB
Supported on: BNB Chain
*Wrapped BNB (WBNB) is also supported.*
## POL
Supported on: Polygon
*Formerly known as MATIC, renamed to POL.*
*Wrapped POL (WPOL) is also supported.*
## SOL
Supported on: Solana
*Wrapped SOL (WSOL) is also supported.*
## BTC
Supported on: Bitcoin, Lightning, Ethereum, Arbitrum One, BNB Chain, Polygon, Base, Solana
*Wrapped Bitcoin (WBTC) is also supported. On Ethereum, Arbitrum One, BNB Chain, Polygon, Base, and Solana.*
## LTC
Supported on: Litecoin
# TypeScript
Source: https://docs.zenobank.io/typescript-sdk
Official TypeScript SDK for Zeno Bank
Install and docs on npm.
# Wallets
Source: https://docs.zenobank.io/wallets
Understand the differences between our managed wallet and the bring-your-own-wallet option.
You have two options for receiving payments: **Managed Wallet** and **Bring Your Own Wallet**.
## Managed Wallet
The managed wallet is the **default and recommended option**. We take care of the security of the funds so you don't have to worry about anything other than receiving payments. This is the option that the majority of stores use.
## Bring Your Own Wallet
With this option, **you provide the wallet address where you want to receive the funds**. You are fully responsible for the security of those funds. After each payment, we send the funds directly to the wallet address you specified.
We recommend this option only if you have a wallet where you control the private key.
Do not use an exchange deposit address (e.g., Binance) here. Exchange
addresses are unique for each token and network, but this address receives
payments in **any** token on **any** compatible network, which can cause
**permanent loss of funds**.
# Withdrawals
Source: https://docs.zenobank.io/withdrawals
Withdraw your crypto funds to your own wallet, with automatic conversion, transparent fees, and fast processing times.
## How Withdrawals Work
If you are using managed wallet mode, you can withdraw your funds to your own wallet.
You can review the applicable fees on the [Fees](/fees) page.
## Processing Time
Withdrawals may take up to 24 hours to be processed, but they are normally completed much faster.
## Currency Conversion
You don't need to worry about conversion. We will automatically convert your funds to your chosen withdrawal token at no additional fees or markup.
## Fiat Withdrawals
We do not currently support direct withdrawals to fiat. However, if you [contact our support team](http://zenobank.io/support), we can assist you through a third-party service.