Appearance
Card payments
Take Visa and Mastercard payments on a hosted checkout page. You send the payment, Payd returns a checkout link, and your customer pays on that page.
POST
https://api.payd.money/api/v2/payments/payinSwitch card payments on first
Card payments are off until Payd turns them on for your account. Email support@paydhq.com with your account id. Until then, card requests return 403 permission_denied.
How it works
- You send the payin with
transaction_channelset tocard. - Payd returns a
checkout_url. Send the customer there. - The customer pays on the checkout page and returns to your
redirect_url. - Payd posts a webhook with
statussuccess. - Payd holds card money for 72 hours in case of a chargeback, then releases it to your balance and posts a second webhook,
payin.settled, withstatussettled.
Request
bash
curl https://api.payd.money/api/v2/payments/payin \
-u "$PAYD_API_USERNAME:$PAYD_API_PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"amount": 2500,
"currency": "KES",
"transaction_channel": "card",
"customer": {
"first_name": "Amina",
"last_name": "Wanjiru",
"email": "amina@example.com",
"phone_number": "254712345678"
},
"vendor_config": { "account_id": "4f28836c-2f1e-4d9b-9a51-6f3c2b1d8e70" },
"provider_config": {},
"payment_config": {
"remark": "Order 8842",
"reference": "order-8842",
"callback_url": "https://example.com/webhooks/payd"
},
"redirect_url": "https://example.com/orders/8842/paid"
}'js
const auth = Buffer.from(
`${process.env.PAYD_API_USERNAME}:${process.env.PAYD_API_PASSWORD}`,
).toString('base64')
const res = await fetch('https://api.payd.money/api/v2/payments/payin', {
method: 'POST',
headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: 2500,
currency: 'KES',
transaction_channel: 'card',
customer: {
first_name: 'Amina',
last_name: 'Wanjiru',
email: 'amina@example.com',
phone_number: '254712345678',
},
vendor_config: { account_id: process.env.PAYD_ACCOUNT_ID },
provider_config: {},
payment_config: {
reference: 'order-8842',
callback_url: 'https://example.com/webhooks/payd',
},
redirect_url: 'https://example.com/orders/8842/paid',
}),
signal: AbortSignal.timeout(35_000),
})
const { gateway_response: payment } = await res.json()
// Save payment.merchant_reference with the order, then send the customer to pay
return Response.redirect(payment.checkout_url, 303)python
import os
import requests
res = requests.post(
"https://api.payd.money/api/v2/payments/payin",
auth=(os.environ["PAYD_API_USERNAME"], os.environ["PAYD_API_PASSWORD"]),
json={
"amount": 2500,
"currency": "KES",
"transaction_channel": "card",
"customer": {
"first_name": "Amina",
"last_name": "Wanjiru",
"email": "amina@example.com",
"phone_number": "254712345678",
},
"vendor_config": {"account_id": os.environ["PAYD_ACCOUNT_ID"]},
"provider_config": {},
"payment_config": {"reference": "order-8842", "callback_url": "https://example.com/webhooks/payd"},
"redirect_url": "https://example.com/orders/8842/paid",
},
timeout=35,
)
res.raise_for_status()
payment = res.json()["gateway_response"]
# Save payment["merchant_reference"] with the order, then redirect to payment["checkout_url"]Fields
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Amount to charge. |
currency | string | Yes | Currency to charge in. Payd confirms which currencies your account can charge when it turns card payments on. |
transaction_channel | string | Yes | card. |
customer.first_name, customer.last_name | string | Yes | Cardholder's name. |
customer.email | string | Yes | Cardholder's email. The checkout page uses it for the receipt. |
customer.phone_number | string | Yes | Cardholder's phone number in international form. |
vendor_config.account_id | string | Yes | Your account id. |
provider_config | object | Yes | Send {}. |
payment_config.reference | string | No | Your own id for the payment. |
payment_config.callback_url | string | No | Where Payd posts the result. |
redirect_url | string | No | Where the checkout page sends the customer after they pay. |
Response
json
{
"gateway_response": {
"success": true,
"merchant_reference": "9BD103512274eR",
"checkout_url": "https://checkout.example/pay/7c1e9a52"
}
}Send the customer to checkout_url, in the same tab or a new one.
When the customer comes back
The checkout page sends the customer to your redirect_url with some query parameters added. Do not trust the visit itself: anyone can open that URL. Look up the order's merchant_reference and check the status before you show "Payment received".
Settlement
Webhook status | Meaning | Your balance |
|---|---|---|
success | The card was charged. | The amount shows as inflight_balance on the balances endpoint. |
settled | Payd released the money. | The amount moves to your available balance. |
You can ship once the payment is success. The hold only affects when you can pay the money out.

