Choose an environment
Zentra keeps test traffic isolated by route. Your API key works in both modes; the URL decides whether a payment is simulated or sent for processing.
Live: https://api.zentra.solutions/api/v1/payment
Test: https://api.zentra.solutions/api/v1/test/paymentSeparate test from live
Live/api/v1/payment/create · /api/v1/payment/status — routes via assigned MID.
Test/api/v1/test/payment/create · /api/v1/test/payment/status — simulated, no merchant gateway credentials.
Start in test mode while you build. Move to live only after your status and webhook handling are ready. Live traffic uses the MID assigned to your account.
Sign every request
Create a secret key in Developers. Keep it on your server and send it as a bearer token or X-API-Key header.
Authorization: Bearer zentra_xxxxxxxxxxxxxxxx
X-API-Key: zentra_xxxxxxxxxxxxxxxxSend your first charge
Submit the customer, billing, card, and order details in one server-side request. Your merchant_transaction_id is echoed back beside Zentra's transaction_id.
Request body
first_nameCustomer first name
last_nameCustomer last name
emailValid email address
card_numberFull card number (digits only)
card_expiry_monthTwo-digit month, e.g. 01
card_expiry_yearFour-digit year, e.g. 2028
card_cvvCard CVV/CVC
amountCharge amount, e.g. 86.40
currencyISO currency code, e.g. GBP
merchant_transaction_idYour unique order/reference ID
line1Billing address line 1
cityBilling city
stateBilling state/province
postal_codeBilling postal code
countryISO country code, e.g. US
phoneCustomer phone number
ip_addressCustomer IP address
return_urlRedirect URL after payment completion
curl -X POST https://api.zentra.solutions/api/v1/payment/create \
-H "Authorization: Bearer zentra_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Maya",
"last_name": "Chen",
"line1": "24 Merchant Square",
"country": "GB",
"state": "Greater London",
"city": "London",
"postal_code": "W2 1JQ",
"ip_address": "203.0.113.42",
"email": "maya.chen@northstar-demo.test",
"phone": "+442079460321",
"amount": "86.40",
"currency": "GBP",
"card_number": "4242424242424242",
"card_expiry_month": "01",
"card_expiry_year": "2028",
"card_cvv": "123",
"return_url": "https://checkout.northstar-demo.test/payments/complete",
"merchant_transaction_id": "NORTHSTAR-2048"
}'Success
{
"status": "success",
"reason": "Payment completed",
"merchant_transaction_id": "NORTHSTAR-2048",
"transaction_id": "txn_znt_8Qm2Kp7Ls4Nd"
}3DS (test only)
Use card 4000000000003220 or amount 500+. Redirect to 3ds_url, then poll test status with the same merchant_transaction_id.
curl -X POST https://api.zentra.solutions/api/v1/test/payment/create \
-H "Authorization: Bearer zentra_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Maya",
"last_name": "Chen",
"line1": "24 Merchant Square",
"country": "GB",
"state": "Greater London",
"city": "London",
"postal_code": "W2 1JQ",
"ip_address": "203.0.113.42",
"email": "maya.chen@northstar-demo.test",
"phone": "+442079460321",
"amount": "200.00",
"currency": "GBP",
"card_number": "4000000000003220",
"card_expiry_month": "01",
"card_expiry_year": "2028",
"card_cvv": "123",
"return_url": "https://checkout.northstar-demo.test/payments/complete",
"merchant_transaction_id": "NORTHSTAR-3DS-2051"
}'{
"status": "processing",
"3ds_url": "https://api.zentra.solutions/test-gateway/authentication/eyJpdiI6...",
"reason": "Payment authentication required.",
"merchant_transaction_id": "NORTHSTAR-3DS-2051",
"transaction_id": "txn_znt_3Ds9Tx6Jv2Qa"
}Declined
Gateway rejection. Status declined.
{
"status": "declined",
"reason": "Payment failed.",
"merchant_transaction_id": "NORTHSTAR-3DS-2051",
"transaction_id": "txn_znt_5Bk4Hn8Rw1Ce"
}Blocked
Zentra stopped the payment before the provider (validation, limits, fraud, country, currency, missing gateway). Status blocked.
{
"status": "blocked",
"reason": "Daily amount limit exceeded.",
"merchant_transaction_id": "NORTHSTAR-3DS-2051",
"transaction_id": "txn_znt_5Bk4Hn8Rw1Ce"
}Validation failed
{
"status": "blocked",
"reason": "The first name field is required.",
"merchant_transaction_id": "NORTHSTAR-3DS-2051",
"transaction_id": "txn_znt_5Bk4Hn8Rw1Ce"
}Retrieve the final state
Look up by merchant_transaction_id or transaction_id. Use the same live/test prefix as create.
curl -X POST https://api.zentra.solutions/api/v1/payment/status \
-H "Authorization: Bearer zentra_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"merchant_transaction_id": "NORTHSTAR-2048"
}'{
"success": true,
"data": {
"transaction_id": "txn_znt_7Lp2Vx9Da6Mf",
"merchant_transaction_id": "NORTHSTAR-2048",
"status": "success",
"amount": 86.4,
"currency": "GBP",
"message": "Payment completed.",
"customer_info": {
"phone": "+442079460321",
"line1": "24 Merchant Square",
"postal_code": "W2 1JQ",
"city": "London",
"state": "Greater London",
"name": "Maya Chen",
"email": "maya.chen@northstar-demo.test",
"country": "GB"
},
"created_at": "2026-10-26 18:19:53 UTC",
"processed_at": "2026-10-26 18:19:53 UTC",
"payment_info": {
"card_number": "4242",
"card_expiry_month": 1,
"card_expiry_year": 2028
}
}
}{
"success": false,
"error": "Transaction not found."
}Read validation failures
When input validation fails, the API returns status: "blocked" with one of these exact messages in reason:
- The first name field is required.
- The last name field is required.
- The email must be a valid email address.
- The card number field is required.
- The card CVV field is required.
Understand card declines
When the gateway or bank rejects a payment, status is declined and reason may be one of:
- Payment failed.
- Insufficient funds.
- Card expired.
- Invalid card number.
- CVV verification failed.
Platform-side blocks (limits, fraud, country, currency, missing gateway) use status: "blocked" instead — see payment.blocked webhooks.
Simulate payment outcomes
Call /api/v1/test/payment/create. Outcome is the test card only — no external processor.
4242424242424242status: success — completed immediately
4000000000000002status: declined — reason: Payment failed.
4000000000003220status: processing + 3ds_url — complete auth, then poll status
Test card library
Test endpoint /api/v1/test/payment:
4242424242424242Success
40000000000032203DS authentication required
4000000000000002Payment failed.
4000000000009995Insufficient funds.
4111111111111111Invalid card number.
Any valid card + CVV 999CVV verification failed.
Any valid card + past expiryCard expired.
Reconcile every payment
merchant_transaction_idYour order reference, e.g. NORTHSTAR-2048. Use it for status lookups and reconciliation.
transaction_idZentra payment reference, e.g. txn_znt_8Qm2Kp7Ls4Nd.
Listen for payment events
Set the URL in Developers. Signed POST on status change or admin refund/chargeback/suspicious (and reversals). HMAC-SHA256 in X-zentra-Signature, event in X-zentra-Event, exponential backoff.
payment.completedPayment succeeds (status success).
payment.declinedProvider/gateway rejects the payment (status declined).
payment.blockedZentra blocks the payment before the provider — validation, limits, fraud, country, currency, or missing gateway (status blocked).
payment.refundedA successful payment is marked as refunded.
payment.chargebackA chargeback is recorded on a payment.
payment.suspiciousA payment is marked suspicious.
payment.refund.reversedA refund is reversed (return refund).
payment.chargeback.reversedA chargeback is reversed (return chargeback).
payment.suspicious.clearedA suspicious flag is cleared (return suspicious).
Body: event, timestamp, data. Lifecycle fields refund_status, chargeback_status, risk_level when relevant.
{
"event": "payment.completed",
"timestamp": "2026-10-26T18:19:53.000Z",
"data": {
"transaction_id": "txn_znt_7Lp2Vx9Da6Mf",
"merchant_transaction_id": "NORTHSTAR-2048",
"status": "success",
"amount": 86.4,
"currency": "GBP",
"message": "Payment completed.",
"customer_info": {
"phone": "+442079460321",
"line1": "24 Merchant Square",
"postal_code": "W2 1JQ",
"city": "London",
"state": "Greater London",
"name": "Maya Chen",
"email": "maya.chen@northstar-demo.test",
"country": "GB"
},
"created_at": "2026-10-26 18:19:53 UTC",
"processed_at": "2026-10-26 18:19:53 UTC",
"payment_info": {
"card_number": "4242",
"card_expiry_month": 1,
"card_expiry_year": 2028
}
}
}{
"event": "payment.blocked",
"timestamp": "2026-10-26T18:19:53.000Z",
"data": {
"transaction_id": "txn_znt_5Bk4Hn8Rw1Ce",
"merchant_transaction_id": "NORTHSTAR-2048",
"status": "blocked",
"amount": 86.4,
"currency": "GBP",
"message": "Daily amount limit exceeded.",
"customer_info": {
"phone": "+442079460321",
"line1": "24 Merchant Square",
"postal_code": "W2 1JQ",
"city": "London",
"state": "Greater London",
"name": "Maya Chen",
"email": "maya.chen@northstar-demo.test",
"country": "GB"
},
"created_at": "2026-10-26 18:19:53 UTC",
"processed_at": "2026-10-26 18:19:53 UTC",
"payment_info": {
"card_number": "4242",
"card_expiry_month": 1,
"card_expiry_year": 2028
}
}
}{
"event": "payment.refunded",
"timestamp": "2026-10-27T09:15:00.000Z",
"data": {
"transaction_id": "txn_znt_7Lp2Vx9Da6Mf",
"merchant_transaction_id": "NORTHSTAR-2048",
"status": "success",
"amount": 86.4,
"currency": "GBP",
"message": "Payment completed.",
"refund_status": "refunded",
"refund_reason": "Customer requested refund",
"refund_processed_at": "2026-10-27 09:15:00 UTC",
"customer_info": { "email": "maya.chen@northstar-demo.test", "country": "GB" },
"created_at": "2026-10-26 18:19:53 UTC",
"processed_at": "2026-10-26 18:19:53 UTC",
"payment_info": {
"card_number": "4242",
"card_expiry_month": 1,
"card_expiry_year": 2028
}
}
}
