Overview · Which API key? · Authentication & Requests · Test & Live Mode · Start a Payment · Payment Result · Confirm a Payment · Create an Escrow · Escrow Checkout · See it in action · Plugins · Create an Invoice · Errors · Security · Currencies
The DroppCash API lets your website or app accept payments and take payments through escrow. With a user API key you can also create escrows and send invoices. Everything below is a plain HTTPS request, so you can use any language.
How a payment works
POST /payment/process with the amount, currency and your own order reference. You get back a url.url. The buyer signs in with their DroppCash account and confirms the payment.web_hook and redirects the buyer to your success_url.GET /payment/check-validity to confirm the payment is real, then delivers the goods.DroppCash has two kinds of accounts, and each one has its own API access key. Both keys work the same way and use the same addresses. They differ in who gets paid and in what you can create.
| What | Merchant API key | User API key |
|---|---|---|
| Where to get it | Merchant dashboard, API key page | User dashboard, API key page |
| Made for | A business or shop that sells to customers | A person, marketplace or platform that also sends money, escrows and invoices |
| Start a payment and confirm it | Yes. You are paid into your merchant wallet | Yes. You are paid into your user wallet |
| Escrow Checkout (your customer pays you through escrow) | Yes. Paid into your merchant wallet when the buyer releases | Yes. Paid into your user wallet when the buyer releases |
| Create an Escrow (you put your own money in escrow for someone) | No (answers with code 403) | Yes |
| Create an Invoice | No (answers with code 403) | Yes |
| Name the buyer sees at checkout | Your business name | Your account name |
1. Get your API access key. Log in to the account that should be paid and open its API key page: in the merchant dashboard for a business, or in the user dashboard for an individual (see Which API key should I use?). No account yet? Sign up as a merchant or as a user. Use the key only on your server and never put it in a web page or mobile app. Creating a new key stops the old one working.
2. Send it as a Bearer token in the Authorization header of every request:
Authorization: Bearer YOUR_ACCESS_KEY
Accept: application/json
Content-Type: application/json
3. Send your data as JSON (recommended) or as normal form fields. Both work.
| Item | Value |
|---|---|
| Base URL | https://droppcash.app |
| Start a payment | POST /payment/process |
| Confirm a payment | GET /payment/check-validity |
| Create an escrow | POST /payment/make-escrow |
| Create an invoice | POST /payment/create-invoice |
code field in the response body. The HTTP status is 200 even when the request fails. A success has "code": 200; anything else is an error (see Errors).In your dashboard (merchant or user) you can set the API service mode to test or active (live). Each key has its own mode.
In both modes the buyer signs in with a DroppCash account during checkout, so create a second test account to play the buyer. In live mode that account also needs a wallet in the payment currency with enough balance.
POST https://droppcash.app/payment/process
| Param | Type | Description |
|---|---|---|
currency_code | string, max 4 | Currency to charge, e.g. USD, NGN, BTC. Must be one of the supported currencies. Required |
amount | number | Amount to charge, greater than 0, with a decimal point (e.g. 0.02). Crypto currencies allow up to 8 decimal places; other currencies use 2. Required |
custom | string, max 20 | Your own order or customer reference. It is returned to you after payment so you can match it to your order. Required |
details | string, max 255 | What the buyer is paying for. Required |
customer_email | email, max 30 | Buyer email address. Required |
web_hook | URL | Your server URL that receives the payment result (server to server). Required |
success_url | URL | Where the buyer is sent after paying. Required |
cancel_url | URL | Where the buyer is sent if they cancel. Required |
The access key is not a body parameter. Send it in the Authorization: Bearer header.
What the buyer sees and pays
amount. The DroppCash payment fee is taken out of what you receive, and the charge field of the result shows it.cURL
curl -X POST https://droppcash.app/payment/process \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"custom": "ORDER-1001",
"currency_code": "USD",
"amount": 280.00,
"details": "Digital Product",
"web_hook": "https://yoursite.com/web_hook.php",
"success_url": "https://yoursite.com/success",
"cancel_url": "https://yoursite.com/cancel",
"customer_email": "customer@mail.com"
}'
PHP
<?php
$parameters = [
'custom' => 'ORDER-1001',
'currency_code' => 'USD',
'amount' => 280.00,
'details' => 'Digital Product',
'web_hook' => 'https://yoursite.com/web_hook.php',
'success_url' => 'https://yoursite.com/success',
'cancel_url' => 'https://yoursite.com/cancel',
'customer_email' => 'customer@mail.com',
];
$ch = curl_init('https://droppcash.app/payment/process');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Content-Type: application/json',
'Authorization: Bearer YOUR_ACCESS_KEY',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($response['code'] ?? 0) === 200) {
header('Location: ' . $response['url']); // send the buyer to checkout
exit;
}
echo 'Error: ' . json_encode($response['message'] ?? 'Unknown error');
Node.js
// Node.js 18+ (run this on your server, never in the browser)
const res = await fetch('https://droppcash.app/payment/process', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_KEY',
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
custom: 'ORDER-1001',
currency_code: 'USD',
amount: 280.0,
details: 'Digital Product',
web_hook: 'https://yoursite.com/web_hook',
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
customer_email: 'customer@mail.com',
}),
});
const data = await res.json();
if (data.code === 200) {
// redirect the buyer to data.url
} else {
console.error(data.message);
}
Python
import requests
r = requests.post(
"https://droppcash.app/payment/process",
headers={"Authorization": "Bearer YOUR_ACCESS_KEY"},
json={
"custom": "ORDER-1001",
"currency_code": "USD",
"amount": 280.00,
"details": "Digital Product",
"web_hook": "https://yoursite.com/web_hook",
"success_url": "https://yoursite.com/success",
"cancel_url": "https://yoursite.com/cancel",
"customer_email": "customer@mail.com",
},
timeout=30,
)
data = r.json()
if data["code"] == 200:
checkout_url = data["url"] # redirect the buyer here
else:
print(data["message"])
Success response
{
"code": 200,
"status": "OK",
"payment_id": "AIYmQIOAz0GlmsjfhgiOeu304",
"message": "Your payment has been processed. Please follow the URL to complete the payment.",
"url": "https://droppcash.app/process-checkout?payment_id=AIYmQIOAz0GlmsjfhgiOeu304"
}
Save the payment_id with your order and redirect the buyer to url.
When the buyer pays, DroppCash does two things with the same data:
POST to your web_hook URL. Respond with any 2xx status. The reply is not read and the call is not retried.success_url with the same fields added as a query string (?code=200&status=OK&payment_id=...).| Field | Description |
|---|---|
code, status | 200 and OK for a completed payment |
payment_id | The ID returned when you started the payment |
transaction | The DroppCash transaction reference |
amount | Amount paid (up to 3 decimal places) |
charge | The fee applied to this payment |
currency | Currency code |
custom | Your reference from the request |
date | Payment date, DD-MM-YYYY |
PHP webhook example
<?php
// web_hook.php - receives the payment result from DroppCash
$paymentId = $_POST['payment_id'] ?? '';
$custom = $_POST['custom'] ?? '';
// 1. Never trust this request on its own. Ask DroppCash if the payment is real
// (see "Confirm a Payment" below).
// 2. Match $custom and the amount with YOUR order record.
// 3. Make sure you only fulfil each order once - the webhook can arrive
// together with the buyer's redirect.
http_response_code(200);
Node.js webhook example
// Node.js (Express) webhook example
app.use(express.urlencoded({ extended: false }));
app.post('/web_hook', async (req, res) => {
const { payment_id, custom } = req.body;
// 1. confirm with check-validity (next section)
// 2. match custom and amount with your own order
// 3. fulfil the order once only
res.sendStatus(200);
});
success_url.GET https://droppcash.app/payment/check-validity?payment_id=PAYMENT_ID
Send the payment_id as a query parameter and your access key in the Authorization header. This must be a GET request.
cURL
curl -G https://droppcash.app/payment/check-validity \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
--data-urlencode "payment_id=AIYmQIOAz0GlmsjfhgiOeu304"
PHP
<?php
$paymentId = 'AIYmQIOAz0GlmsjfhgiOeu304';
$ch = curl_init('https://droppcash.app/payment/check-validity?payment_id=' . urlencode($paymentId));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Authorization: Bearer YOUR_ACCESS_KEY',
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($response['code'] ?? 0) === 200) {
// payment is completed - safe to deliver the order
}
Node.js
const url = new URL('https://droppcash.app/payment/check-validity');
url.searchParams.set('payment_id', 'AIYmQIOAz0GlmsjfhgiOeu304');
const res = await fetch(url, {
headers: { 'Authorization': 'Bearer YOUR_ACCESS_KEY', 'Accept': 'application/json' },
});
const data = await res.json();
if (data.code === 200) {
// payment is completed - safe to deliver the order
}
Python
import requests
r = requests.get(
"https://droppcash.app/payment/check-validity",
params={"payment_id": "AIYmQIOAz0GlmsjfhgiOeu304"},
headers={"Authorization": "Bearer YOUR_ACCESS_KEY"},
timeout=30,
)
if r.json()["code"] == 200:
pass # payment is completed - safe to deliver the order
Responses
// Payment completed
{ "code": 200, "status": "OK", "message": "Transaction is valid" }
// Payment not found or not completed yet
{ "code": 404, "status": "error", "message": "Transaction Not Found." }
// Wrong or missing access key
{ "code": 401, "status": "error", "message": "Invalid API credentials." }
custom reference and the amount from the webhook with your own order record.{"code": 403} and the message Merchant API keys cannot be used to create invoices or escrows yet. If you run a shop and want your customers to pay you through escrow, use Escrow Checkout instead. It works with both kinds of key.Escrow holds money safely until it is released to the receiver. It suits marketplaces. The money comes from the user wallet of the account that owns the access key, in the currency you choose, and is taken immediately.
POST https://droppcash.app/payment/make-escrow
| Param | Type | Description |
|---|---|---|
receiver_email | Email of the person who will receive the escrow. They must already have a DroppCash account. Required | |
currency_code | string | Currency of the escrow, e.g. NGN. You need a wallet in this currency. Required |
amount | number | Amount to hold, greater than 0. Required |
description | string | What the escrow is for. Required |
pay_charge | boolean | true: you pay the escrow charge on top of the amount. false: the charge is taken from the amount when it is released. Required |
cURL
curl -X POST https://droppcash.app/payment/make-escrow \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"receiver_email": "seller@mail.com",
"currency_code": "NGN",
"amount": 20,
"description": "Digital Product",
"pay_charge": true
}'
PHP
<?php
$parameters = [
'receiver_email' => 'seller@mail.com',
'currency_code' => 'NGN',
'amount' => 20,
'description' => 'Digital Product',
'pay_charge' => true,
];
$ch = curl_init('https://droppcash.app/payment/make-escrow');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Content-Type: application/json',
'Authorization: Bearer YOUR_ACCESS_KEY',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Responses
// Success
{ "code": 200, "status": "OK", "message": "An Escrow Has Been Made to seller@mail.com" }
// Validation problem (message is a list)
{ "code": 422, "status": "error", "message": ["The selected receiver email is invalid."] }
// Not enough money in your wallet
{ "code": 422, "status": "error", "message": "Insufficent Balance In Your Wallet" }
{"code": 403} and the message Merchant API keys cannot be used to create invoices or escrows yet. To take a payment from a customer with a merchant key, use Start a Payment or Escrow Checkout.Create an invoice for your customer. DroppCash emails them a payment link and also returns it to you so you can redirect them straight to a clean checkout page.
POST https://droppcash.app/payment/create-invoice
| Param | Type | Description |
|---|---|---|
invoice_to | string | Name of the person being invoiced. Required |
email | Customer email. The customer must already have a DroppCash account. Required | |
currency_code | string | Currency the invoice is paid in, e.g. NGN. Required |
item | array of strings | Names of the items. Each name must be unique. Required |
amount | array of numbers | Price of each item, in the same order as item. Both arrays must be the same length and every amount greater than 0. The invoice total is the sum. Required |
address | string | Customer address. Optional |
invoice_status | string | publish makes the invoice payable, cancel cancels it. If left out the invoice is saved as a draft. Optional |
allow_escrow | boolean | true lets the customer pay through escrow. Optional |
pay_charge | boolean | Only matters when the customer pays through escrow: true means the escrow charge is paid on top of the invoice total. Optional |
success_url | URL | Where to send the customer after paying. Optional |
cancel_url | URL | Where to send the customer if they cancel. Optional |
cURL
curl -X POST https://droppcash.app/payment/create-invoice \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"invoice_to": "Test User",
"email": "customer@mail.com",
"currency_code": "NGN",
"item": ["Baby doll", "Toy car", "Gift wrap"],
"amount": [10, 20, 30],
"address": "Lagos, Nigeria",
"allow_escrow": true,
"pay_charge": true,
"invoice_status": "publish",
"success_url": "https://yoursite.com/success",
"cancel_url": "https://yoursite.com/cancel"
}'
PHP
<?php
$parameters = [
'invoice_to' => 'Test User',
'email' => 'customer@mail.com',
'currency_code' => 'NGN',
'item' => ['Baby doll', 'Toy car', 'Gift wrap'],
'amount' => [10, 20, 30],
'address' => 'Lagos, Nigeria',
'allow_escrow' => true,
'pay_charge' => true,
'invoice_status' => 'publish',
'success_url' => 'https://yoursite.com/success',
'cancel_url' => 'https://yoursite.com/cancel',
];
$ch = curl_init('https://droppcash.app/payment/create-invoice');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Content-Type: application/json',
'Authorization: Bearer YOUR_ACCESS_KEY',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (($response['code'] ?? 0) === 200) {
header('Location: ' . $response['url']); // customer pays on the invoice page
exit;
}
Responses
// Success
{
"code": 200,
"status": "OK",
"message": "Invoice Has Been Made",
"url": "https://droppcash.app/view-invoice/eyJpdiI6..."
}
// Customer email has no account (a link to register is returned)
{ "code": 500, "status": "OK", "message": "User Not Registerred On Dropppay", "url": "https://droppcash.app/user/register" }
// item and amount lists do not match
{ "code": 500, "status": "error", "message": "An Error In Your API Parameters Caused This." }
With escrow checkout the buyer pays into DroppCash escrow instead of paying you directly. The money is held safely until the buyer releases it to you. You are the seller: the account that owns the API access key is the one that gets paid. This works with both merchant keys and user keys: a merchant key is paid into the merchant wallet, a user key into the user wallet. The buyer sees your business name (merchant key) or your account name (user key) on the checkout.
POST /payment/escrow/process and gets a checkout url.success_url and calls your web_hook with event escrow.funded. You can now ship the goods or deliver the service.escrow.released and the money is in your wallet.| Endpoint | What it does |
|---|---|
POST /payment/escrow/process | Start an escrow payment and get the buyer checkout URL |
GET /payment/escrow/status | Check the current state of an escrow payment |
POST /payment/escrow/refund | Return the held money to the buyer (while it is still held) |
POST /payment/escrow/simulate | Test mode only: pretend to be the buyer (release or dispute) |
Merchant accounts have no escrow screen in the dashboard yet, so follow an escrow with the status call and the webhooks below.
Start an escrow payment takes the same fields as Start a Payment (currency_code, amount, custom, details, customer_email, web_hook, success_url, cancel_url) plus one optional field:
| Param | Type | Description |
|---|---|---|
pay_charge | boolean | true: the buyer pays the escrow fee on top of the amount. false (default): the fee is taken from the amount when the money is released to you. Optional |
cURL
curl -X POST https://droppcash.app/payment/escrow/process \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"currency_code": "NGN",
"amount": 7500.50,
"custom": "ORDER-1001",
"details": "Laptop bag",
"customer_email": "buyer@mail.com",
"web_hook": "https://yoursite.com/webhook.php",
"success_url": "https://yoursite.com/success.php",
"cancel_url": "https://yoursite.com/cancel.php",
"pay_charge": false
}'
{
"code": 200,
"status": "OK",
"payment_id": "AIYmQIOAz0GlmsjfhgiOeu304",
"message": "Your escrow payment has been created. Please send the buyer to the URL to fund the escrow.",
"url": "https://droppcash.app/payment/process-checkout?payment_id=AIYmQIOAz0GlmsjfhgiOeu304"
}
Check the status with GET /payment/escrow/status?payment_id=... (Bearer key). Always use this call, never the address bar, to confirm what happened.
{
"code": 200,
"status": "OK",
"escrow": {
"payment_id": "AIYmQIOAz0GlmsjfhgiOeu304",
"custom": "ORDER-1001",
"amount": "7500.5",
"currency": "NGN",
"test": 0,
"escrow_id": "42",
"escrow_status": "held",
"transaction": "K3JD8SL2QW1X",
"charge": "75",
"funded_at": "2026-10-16T10:15:00+00:00"
}
}
| escrow_status | Meaning |
|---|---|
awaiting_payment | The buyer has not funded the escrow yet |
held | Funded: the money is held. You can ship or deliver. |
released | The buyer released the money to you |
disputed | A dispute is open. DroppCash support decides who gets the money. |
refunded | The money went back to the buyer |
released_by_admin | DroppCash support decided in your favour and paid you |
closed | The escrow was closed with no payout |
Refund the buyer (only while the status is held): POST /payment/escrow/refund with {"payment_id": "..."}. The buyer gets back everything they paid: the held amount, plus the escrow fee if the buyer paid it (pay_charge true). The response shows the refunded total.
{ "code": 200, "status": "OK", "message": "Escrow refunded to the buyer.", "refunded": "7575.5" }
// not refundable (already released, disputed or refunded)
{ "code": 422, "status": "error", "message": "Escrow can only be refunded while it is held." }
Webhook events. DroppCash sends a form-encoded POST to your web_hook URL every time something happens. Events: escrow.funded, escrow.released, escrow.refunded, escrow.disputed, escrow.closed. Answer with any 2xx status. Calls are not retried, so also use the status call as a safety net.
| Field | Description |
|---|---|
event | One of the events above |
status | The escrow_status after the event |
payment_id, escrow_id | Identify the payment and the escrow |
transaction | DroppCash transaction reference |
amount, currency, custom | Amount, currency and your own reference from the request |
test | 1 for a test-mode event, 0 for live |
date | Time of the event (ISO 8601) |
Every webhook is signed. The header X-DroppCash-Signature holds sha256= followed by the HMAC-SHA256 of the raw request body, using your API access key as the secret. Reject any call whose signature does not match, then also check that amount and currency match your order.
PHP
<?php
$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_DROPPCASH_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $raw, 'YOUR_ACCESS_KEY');
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit;
}
parse_str($raw, $event); // $event['event'], $event['payment_id'], ...
Node.js
// Node.js (Express): use express.raw({ type: '*/*' }) so you get the raw body
const crypto = require('crypto');
app.post('/webhook', express.raw({ type: '*/*' }), (req, res) => {
const expected = 'sha256=' + crypto.createHmac('sha256', 'YOUR_ACCESS_KEY').update(req.body).digest('hex');
const given = req.get('X-DroppCash-Signature') || '';
const ok = expected.length === given.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(given));
if (!ok) return res.sendStatus(401);
const event = Object.fromEntries(new URLSearchParams(req.body.toString()));
res.sendStatus(200);
});
Python
import hmac, hashlib
from urllib.parse import parse_qs
def is_genuine(raw_body: bytes, signature_header: str, access_key: str) -> bool:
expected = "sha256=" + hmac.new(access_key.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header or "")
# event = {k: v[0] for k, v in parse_qs(raw_body.decode()).items()}
Test mode. With a test-mode key nothing is charged and no real escrow exists, but the whole flow works: checkout, redirect, webhooks, status and refund. Because no real buyer is there to release the money, use POST /payment/escrow/simulate with {"payment_id": "...", "action": "released"} (or "disputed") to act as the buyer. This call is refused for live payments.
409 and tells you to use /payment/escrow/status.The screenshot below is from a live integration: an online healthcare booking platform (DocPlus) that takes DroppCash payments for its appointments. Patients pay with DroppCash, and the platform marks each appointment Paid the moment our API confirms the money. Everything on that screen is built from the calls and webhooks documented above — nothing else is installed.
How the screen maps to the API
| On the screen | Where it comes from |
|---|---|
| Amount (NGN 20,370.00) | The amount and currency_code from the Start a Payment or Create an Escrow request |
| Payment Status Paid | A flag on the platform's own order, set only after Confirm a Payment returns code 200 (normal payment) or the signed escrow.funded webhook arrives (escrow) — never from the success redirect alone |
| Date | When checkout was completed; the platform stores it together with the payment_id |
| Status and actions (Approve, Complete, Add Prescription, Video Call) | The platform's own business logic. DroppCash only tells it that the money is confirmed or safely held. |
End to end for one appointment (escrow checkout, the amounts from the screenshot):
# 1. Patient clicks Pay — the platform starts an escrow payment
curl -X POST https://droppcash.app/payment/escrow/process \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"currency_code": "NGN",
"amount": 20370.00,
"custom": "APT-2043",
"details": "Consultation with Dr. Adeyemi",
"customer_email": "patient@mail.com",
"web_hook": "https://theplatform.com/droppcash/webhook",
"success_url": "https://theplatform.com/appointment/2043/paid",
"cancel_url": "https://theplatform.com/appointment/2043"
}'
// 2. The patient funds the escrow at the checkout URL. This signed webhook arrives:
event=escrow.funded&status=held&payment_id=AIYmQIOAz0GlmsjfhgiOeu304&escrow_id=42
&transaction=K3JD8SL2QW1X&amount=20370¤cy=NGN&custom=APT-2043&test=0
&date=2026-11-03T13:58:02+00:00
// 3. The platform verifies the X-DroppCash-Signature header, matches custom and
// amount to its order, and only then marks the appointment Paid.
// 4. After the consultation the patient releases the payment (escrow.released)
// and the money lands in the merchant wallet.
/payment/escrow/simulate to play the buyer. See Escrow Checkout for the full reference.DroppCash ships an official plugin for each of the major store platforms. A plugin connects your shop in minutes: you paste your access key, choose the mode, and the plugin does the rest — it starts the payment, receives the webhook, verifies the money, and only then marks the order paid. Every plugin is a thin wrapper around the same API documented on this page, and each package ships with its own step-by-step guide (DOCUMENTATION.md or INSTALLATION.md inside the zip).
“Pay with DroppCash” at checkout — classic and block checkout, HPOS ready, scheduled re-checks.
Download .zip ↓ Payments app Shopify Node 20+ host · Shopify Payments Partner approvalOffsite payments app: buyers are sent from the Shopify checkout to DroppCash and back; the app resolves the session only after verifying.
Download .zip ↓ Payment module Magento 2 Magento 2.4.4–2.4.7 · PHP 7.4–8.3Native payment method with the key stored encrypted, its own webhook endpoint and a payment log table.
Download .zip ↓ Payment module PrestaShop PrestaShop 1.7.6, 8.x, 9.x · PHP 7.4+Orders wait in Awaiting DroppCash payment until the payment is confirmed, then become Payment accepted.
Download .zip ↓ Payment extension OpenCart OpenCart 3.0.x & 4.0.2.x · PHP 7.4+One package with an ocmod build for each major version; configurable order statuses and one reusable payment link per order.
Download .zip ↓ Self-hosted app BigCommerce Any Node 20+ host · no partner approvalWorks around BigCommerce's closed checkout: buyers pick a renamed offline method and are redirected to DroppCash from the order confirmation page.
Download .zip ↓ Two routes in one package Wix Premium Wix site, or Wix PSP approvalA Velo plugin for your own store (no approval needed) plus a payment-provider server to offer DroppCash to every Wix merchant.
Download .zip ↓ Direct API Any other platform Any language, any stackStart a Payment or an Escrow Checkout from your own code — that is all a plugin does internally.
Go to the API →What every plugin asks you for — the same three things on every platform:
| Setting | What you enter |
|---|---|
| Access key | Copy it from API Access Key in your DroppCash account and paste it into the plugin settings |
| Mode | Start in Test mode, place a test order, then switch the key to Active when everything works |
| Everything else | Nothing. The plugin creates its own webhook, success and cancel URLs, and sends the platform's order number as custom |
How the plugin is linked to each platform:
| Platform | How to link it |
|---|---|
| WooCommerce (WordPress) | WordPress admin → Plugins → Add New Plugin → Upload Plugin with droppcash-for-woocommerce.zip, activate it, then open WooCommerce → Settings → Payments → DroppCash → Manage: tick Enable, paste the access key, choose the payment type (Standard or Escrow), and tick Live mode only when your DroppCash dashboard is Active. For extra safety the key can live in wp-config.php (DROPPCASH_ACCESS_KEY) instead of the database. Orders become Processing after verification; a scheduled check every 10 minutes catches missed webhooks. |
| Shopify | Shopify only lets approved partners add a payment method at checkout, so this package is a payments app: apply in your Shopify Partner account, host the app (Node 20+) and deploy it with the Shopify CLI. Each merchant opens the app's setup link, approves the install and pastes their access key, which is stored encrypted. Activate DroppCash under Settings → Payments in Shopify admin — test mode first. At checkout the buyer is redirected to DroppCash; the app tells Shopify the payment succeeded only after verifying it. Refund requests land in the app's admin queue for approval. |
| Magento 2 | Unzip so the module sits at app/code/DroppCash/Payment, then run bin/magento module:enable DroppCash_Payment and bin/magento setup:upgrade (plus the compile and static-content steps in production). Configure under Stores → Configuration → Sales → Payment Methods → DroppCash: enabled, title, API access key (checked when you save, stored encrypted), payment type, test mode, fallback email. The webhook address is sent with every payment — keep /droppcash/payment/webhook out of firewall and full-page-cache rules. Orders become Processing with an invoice after verification. |
| PrestaShop | Back Office → Modules → Module Manager → Upload a module with droppcash.zip, then click Configure: title, access key, payment type, test box, fallback email. Finish in Payment → Preferences by ticking DroppCash for the currencies, countries and customer groups you serve. New orders wait in Awaiting DroppCash payment and move to Payment accepted after verification; the confirmation page offers unpaid buyers a Pay now button. |
| OpenCart | Pick the build that matches your shop (4.0.2.x or 3.0.x — both ocmod zips are inside the package; keep the file name droppcash.ocmod.zip). Upload it under Extensions → Installer, then Extensions → Extensions → Payments → DroppCash → Install → Edit: title, access key, payment type, test mode, fallback email and your order statuses. The notice (webhook) address is shown on the settings page and sent to DroppCash with every payment. Hidden for subscription carts and unsupported currencies. |
| BigCommerce | No partner approval needed. Host the small Node app from the package, create a Store-level API account (Orders, Content and Checkout Content: Modify) and fill the .env with the store hash, the access token and your DroppCash key. Enable any offline payment method, rename it DroppCash, and run npm run setup to install the confirmation-page script that redirects buyers to DroppCash. Orders move from Awaiting Payment to Awaiting Fulfillment after verification; for customers who never paid, the app can issue an emailed payment link. |
| Wix | Two routes in one package. A. Velo plugin — for one store, no Wix approval: add the service-plugin files in the Velo editor, save the access key in Secrets Manager, create the DroppCashTransactions collection, publish, then connect under Settings → Accept Payments → DroppCash. B. Payment-provider server — to offer DroppCash to every Wix merchant from their dashboard: host the server, register its connect/transaction/refund URLs in a Wix payment-gateway app, and complete Wix's payment-provider onboarding first. |
| Any custom website or app | Use the API directly — Start a Payment or Escrow Checkout. That is all a plugin does internally; the cards above show the wrapper each platform needs. |
How the link works under the hood — identical on every platform:
POST /payment/process (or /payment/escrow/process) with the amount, currency, buyer email, the platform's order reference in custom, and its own web_hook, success_url and cancel_url.X-DroppCash-Signature and carry the events escrow.funded, escrow.released, escrow.disputed and escrow.refunded — see Escrow Checkout.Refunds through the plugins. Escrow, while the money is still held: the refund is full-amount and goes straight back to the buyer. WooCommerce (Refund button on the order), Magento 2 (online credit memo), BigCommerce and Shopify (admin endpoints) and the Wix Velo plugin (refund from Wix Orders) trigger it for you; with PrestaShop and OpenCart you refund from your DroppCash account. Everything else — standard payments, released escrows, partial amounts: DroppCash has no refund call for these, so refund the buyer from your DroppCash account and record it in the shop's admin.
Remember: the HTTP status is always 200. Check the code field in the JSON body.
| code | Meaning | What to do |
|---|---|---|
200 | Success | Continue. |
401 | Invalid API credentials. | The access key is missing or wrong. Check the Authorization: Bearer header. |
404 | Requested currency not found., Transaction Not Found. or Merchant account not found. | Check currency_code against the supported list, or the payment_id. A payment that is not completed yet also returns 404 on check-validity. For escrow, You do not have a wallet in this currency. means the account that owns the key needs a wallet in that currency. |
403 | Merchant API keys cannot be used to create invoices or escrows yet. | Create an Escrow and Create an Invoice need a user API key. For a shop, use Start a Payment or Escrow Checkout instead. |
403 / 409 | Not allowed for this payment (for example simulate on a live payment, or check-validity on an escrow payment) | Use the call that matches the payment type, as the message says. |
422 | Validation failed, or Insufficent Balance In Your Wallet (escrow) | For validation, message is a list of what to fix. For balance, top up your wallet. |
500 | Server problem, or invoice parameters/customer account problem | Check the invoice item and amount lists and that the customer is registered. If it keeps happening, contact support. |
Example validation error:
{
"code": 422,
"status": "error",
"message": [
"The amount must be greater than 0.",
"The success url must be a valid URL."
]
}
custom and the amount with your own order.payment_id against the order and ignore repeats.web_hook, success_url and cancel_url.CURLOPT_SSL_VERIFYHOST or verify=False) in your own code.Use the currency code exactly as shown. The list updates automatically when new currencies are added.
| Currency Name | Currency Symbol | Currency Code |
|---|---|---|
| US Dollar | $ | USD |
| European Euro | € | EUR |
| British Pound | £ | GBP |
| Bangladeshi Taka | ৳ | BDT |
| Bitcoin | BTC | BTC |
| Indian Rupee | ₹ | INR |
| Japanese Yen | ¥ | JPY |
| Nigerian naira | N | NGN |
| Chinese Yuan | CN¥ | CNY |
| South African Rand | R | ZAR |
| Kenyan Shilling | Ksh | KES |
| Emirati Dirham | د.إ | AED |
| Ghanaian Cedi | GH₵ | GHS |
| Canadian Dollar | Can$ | CAD |
| Egyptian Pound | E£ | EGP |
| Rwandan franc | R₣ | RWF |
| Singapore Dollar | S$ | SGD |
| Ugandan Shilling | USh | UGX |
| Turkish Lira | ₺ | TRY |
| Australian Dollar | A$ | AUD |
| Malaysian Ringgit | RM | MYR |
| Romanian leu | lei | RON |
| New Zealand Dollar | NZD | NZD |
| Hungarian forint | Ft | HUF |
| Mexican Peso | Mex$ | MXN |
| Hong Kong Dollar | HK$ | HKD |
| Brazilian Real | R$ | BRL |
| Swiss Franc | CHf | CHF |
| Bulgarian Lev | Лв. | BGN |
| Czech Koruna | Kč | CZK |
| Danish Krone | Kr. | DKK |
| Norwegian Krone | kr | NOK |
| Thai Baht | ฿ | THB |
| Ukrainian hryvnia | ₴ | UAH |
| Polish Zloty | zł | PLN |
| Swedish Krona | skr | SEK |
| Dogecoin | Ɖ | DOGE |
| Litecoin | Ł | LTC |
| Kucoin Token | KCS | KCS |
| Solana | SOL | SOL |
| Binance Coin | BNB | BNB |
| USDT | ₮ | USDT |
| Ethereum | ETH | ETH |
| ADA | ₳ | ADA |
| TRX | TRX | TRX |
| Israeli Shekel | ₪ | ILS |
| West African CFA franc | F.CFA | XOF |
| Central African CFA franc | céfa | XAF |
| Tanzanian shilling | TSh | TZS |
| Zambian Kwacha | ZK | ZMW |