Operations#
Running a live integration: callback delivery and verification, status queries, chargebacks, settlement and reconciliation, testing and go-live.
Settlement#
Settlement Cycle
CentaPay settles to clients on a T+1 (next business day) cycle. Transactions that reach SETTLED status before the daily cutoff are included in the next business day's settlement batch.
| Parameter | Value |
|---|---|
| Cycle | T+1 (next business day) |
| Settlement currency | Agreed at onboarding (typically USD) |
Transaction Status Lifecycle
How a transaction moves through the system toward settlement:
| Status | Meaning |
|---|---|
PENDING | AUTH hold placed — funds reserved on cardholder's account but not yet captured |
PREPARE | Processing in progress — final status not yet determined |
3DS | Awaiting cardholder 3DS authentication |
REDIRECT | Awaiting redirect completion |
SETTLED | Transaction completed successfully. Funds will be included in the next settlement batch to you. |
DECLINED | Transaction rejected by issuer or risk engine |
VOID | Same-day cancellation — no funds movement |
REFUND | Full refund processed — amount deducted from your settlement balance |
REVERSAL | AUTH hold released (no capture occurred) |
CHARGEBACK | Issuer-initiated dispute — amount debited from your settlement balance |
SETTLED status. The partial refund amount is deducted from your settlement balance. Use GET_TRANS_DETAILS to see the full transaction history including partial refund entries.FX & Currency Conversion
When the transaction currency differs from your settlement currency, CentaPay applies a foreign exchange conversion. The applicable rate is included in callback parameters:
| Callback Field | Description |
|---|---|
exchange_rate | FX rate applied to the transaction |
exchange_rate_base | Base conversion rate (if double conversion applies) |
exchange_currency | Original transaction currency |
exchange_amount | Original transaction amount before conversion |
Settlement Reports
Settlement reports are available via the admin panel and include transaction-level detail for reconciliation against your callback records. Contact [email protected] for details on report format, delivery schedule, and available export options for your account.
Querying Settlement Status
Use GET_TRANS_STATUS or GET_TRANS_DETAILS to check whether a transaction has settled.
GET_TRANS_STATUS returns the current status field. A value of SETTLED confirms the transaction completed successfully and will be included in settlement.
GET_TRANS_DETAILS returns the full order history including an array of all sub-transactions (sale, 3ds, auth, capture, credit, chargeback, reversal, refund) with individual dates, statuses, and amounts.
GET_TRANS_STATUS for settlement confirmation. Use callbacks as the authoritative source. Reserve status queries for reconciliation or when a callback has not arrived within your expected window.Settlement & Reporting#
PSP clients receive a single aggregated settlement per cycle covering all sub-merchant transactions.
| Parameter | Value |
|---|---|
| Cycle | T+1 (next business day) |
| Settlement currency | Agreed at onboarding (typically USD) |
| Scope | All sub-merchants under your account, aggregated |
Each transaction callback includes order_id (your reference), trans_id (CentaPay reference), and channel_id (if provided) for sub-merchant-level reconciliation.
Use GET_TRANS_DETAILS to retrieve the full history of any transaction, including payer details, masked card, and all status transitions.
rrn, approval_code, connector_name, and other acquirer-level fields in callbacks — useful for cross-referencing with upstream acquirer reports.For details on sub-merchant settlement breakdowns and report formats, contact [email protected].
Transaction Status (GET_TRANS_STATUS)#
Query the current status of a transaction. Use when a callback hasn't arrived or for reconciliation.
| Parameter | Description | Required |
|---|---|---|
action | GET_TRANS_STATUS | Yes |
client_key | Your account key | Yes |
trans_id | CentaPay transaction ID | Yes |
hash | Formula 2 (or Formula 6 for CREDIT2CARD) | Yes |
Response includes status (one of: 3DS, REDIRECT, PENDING, PREPARE, DECLINED, SETTLED, REVERSAL, REFUND, VOID, CHARGEBACK), plus decline_reason if declined, and recurring_token / schedule_id / digital_wallet if applicable, arn* if configured.
SETTLED is the terminal success status — the transaction has been authorised and captured, and will be included in the next settlement batch to you. For the full settlement lifecycle and status definitions, see Settlement.Transaction Details (GET_TRANS_DETAILS)#
Returns full order history including payer details, card mask, and an array of all transactions in the order.
| Parameter | Description | Required |
|---|---|---|
action | GET_TRANS_DETAILS | Yes |
client_key | Your account key | Yes |
trans_id | CentaPay transaction ID | Yes |
hash | Formula 2 (or Formula 6 for CREDIT2CARD) | Yes |
Response includes: name, mail, ip, amount, currency, card (masked), decline_reason if declined, recurring_token, schedule_id, pan_type, digital_wallet, arn* if configured, and a transactions array with entries containing date, type (sale, 3ds, auth, capture, credit, chargeback, reversal, refund), status, and amount.
Status by Order ID (GET_TRANS_STATUS_BY_ORDER)#
Look up the most recent transaction status using your order_id instead of trans_id. Useful when trans_id is lost or for reconciliation.
| Parameter | Description | Required |
|---|---|---|
action | GET_TRANS_STATUS_BY_ORDER | Yes |
client_key | Your account key | Yes |
order_id | Your order ID | Yes |
hash | Formula 7 (or Formula 6 for CREDIT2CARD) | Yes |
Response: status (3DS/REDIRECT/PENDING/PREPARE/DECLINED/SETTLED/REVERSAL/REFUND/VOID/CHARGEBACK), decline_reason if declined, recurring_token, schedule_id, digital_wallet if applicable. With cascading enabled, returns most recent transaction only.
Chargebacks#
Chargebacks are initiated by the issuing bank, not by API request. CentaPay sends a callback notification when a chargeback occurs.
| Callback Parameter | Description |
|---|---|
action | CHARGEBACK |
result | SUCCESS |
status | CHARGEBACK |
order_id | Your order ID |
trans_id | CentaPay transaction ID |
amount | Chargeback amount |
chargeback_date | System date of the chargeback |
bank_date | Bank date of the chargeback |
reason_code | Chargeback reason code |
connector_name* | Payment gateway name |
rrn* | Retrieval Reference Number |
approval_code* | Issuer authorisation code |
gateway_id* / extra_gateway_id* | Gateway transaction identifiers |
merchant_name* / mid_name* | Merchant and MID names |
issuer_country* / issuer_bank* | Card issuer details |
hash | Formula 2 |
* Extended data fields - included only if configured in admin panel (Configuration → Protocol Mappings → "Add Extended Data to Callback").
Callback Delivery Rules#
CentaPay sends HTTP POST callbacks to your notification URL as transaction states change. Always use callbacks — not the synchronous response — as the authoritative result.
Content Type
Callbacks are sent as application/x-www-form-urlencoded.
Required Response
Your endpoint must return the plain string OK — nothing else. Any other content, HTML, or timeout is treated as a failure.
When Callbacks Are Sent
| Transaction Type | Callback Sent On |
|---|---|
| SALE, CREDITVOID, RECURRING_SALE | SUCCESS, FAIL, WAITING, UNDEFINED |
| CAPTURE, VOID, CREDIT2CARD | SUCCESS, FAIL, UNDEFINED |
| CHARGEBACK | Always (platform-initiated) |
Hash Verification#
Always verify the callback hash before processing. For most actions, use Formula 2. For CREDIT2CARD, use Formula 6. For VOID callbacks, use the Void signature: md5(strtoupper(strrev(trans_id)) . PASSWORD).
email is not included in callback parameters. You must store it from the original SALE request. For SUCCESS callbacks, the card field provides the masked PAN (first 6 + last 4 visible). For DECLINED callbacks, card is not present — use the card mask stored from your original request.$data = $_POST;
// Use card from callback if present (SUCCESS), otherwise use stored mask (DECLINED)
$cardMask = isset($data['card']) ? $data['card'] : $storedCardMask;
$cardPart = substr($cardMask,0,6).substr($cardMask,-4);
$expected = md5(strtoupper(
strrev($storedEmail) . PASSWORD . $data['trans_id'] . strrev($cardPart)
));
if (!hash_equals($expected, $data['hash'])) {
http_response_code(400);
exit('ERROR');
}
// Process based on result
if ($data['result'] === 'SUCCESS') {
fulfillOrder($data['order_id'], $data['trans_id']);
}
echo 'OK';import hashlib, hmac
data = request.form.to_dict()
# Use card from callback if present (SUCCESS), otherwise use stored mask (DECLINED)
card_mask = data.get('card', stored_card_mask)
card_part = card_mask[:6] + card_mask[-4:]
raw = stored_email[::-1] + PASSWORD + data['trans_id'] + card_part[::-1]
expected = hashlib.md5(raw.upper().encode()).hexdigest()
if not hmac.compare_digest(expected, data.get('hash','')):
return 'ERROR', 400
if data['result'] == 'SUCCESS':
fulfill_order(data['order_id'])
return 'OK'const rev = s => s.split('').reverse().join('');
app.post('/webhook', express.urlencoded({extended:false}), (req,res) => {
const d = req.body;
// Use card from callback if present (SUCCESS), otherwise use stored mask (DECLINED)
const cardMask = d.card || storedCardMask;
const cp = cardMask.slice(0,6) + cardMask.slice(-4);
const raw = rev(storedEmail) + PASSWORD + d.trans_id + rev(cp);
const exp = crypto.createHash('md5').update(raw.toUpperCase()).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(exp), Buffer.from(d.hash||'')))
return res.status(400).send('ERROR');
if (d.result === 'SUCCESS') fulfillOrder(d.order_id);
res.send('OK');
});Cascading Behaviour#
When cascading is enabled (auto-retry across MIDs on decline):
- General case: You receive only a callback for the last payment attempt with the final status.
- Particular case: If a redirect is required (e.g. 3DS), you also receive a callback for the first attempt with redirect data. The last-attempt callback includes only the final status.
- Intermediate attempts are not sent. The
trans_idmay differ between first and final callbacks. Do not assume you will receive a first-attempt callback.
Extended Callback Data#
Additional fields if configured in admin panel (Configuration → Protocol Mappings → "Add Extended Data to Callback"): connector_name, rrn, approval_code, gateway_id / extra_gateway_id, merchant_name / mid_name, issuer_country / issuer_bank, brand, arn, extended_data.
Test Cards#
Use these test values in the sandbox environment. All transactions are processed by the test engine — no real funds are moved. Use any 3-digit CVV.
S2S CARD — Scenario Simulation
All scenarios use card number 4111111111111111. The expiry date determines the outcome:
| Expiry | Scenario | Response |
|---|---|---|
01/2038 |
Successful SALE (also use for recurring init — only card that returns recurring_token) |
result: SUCCESS, status: SETTLEDAUTH: status: PENDING |
02/2038 |
Declined SALE / AUTH | result: DECLINED, status: DECLINED |
03/2038 |
Successful AUTH, then declined CAPTURE | AUTH: SUCCESS/PENDINGCAPTURE: DECLINED/PENDING |
05/2038 |
3DS verification → Success | SALE: REDIRECT/3DS → After ACS: SUCCESS/SETTLED |
06/2038 |
3DS verification → Decline | SALE: REDIRECT/3DS → After ACS: DECLINED |
12/2038 |
Redirect → Success | SALE: REDIRECT/REDIRECT → Return: SUCCESS/SETTLED |
12/2039 |
Redirect → Decline | SALE: REDIRECT/REDIRECT → Return: DECLINED |
CREDIT2CARD Test Card
| Card Number | Scenario | Response |
|---|---|---|
4601541833776519 |
Successful card payout | result: SUCCESS, status: SETTLED |
4111111111111111 expiry 01/2038. Other test cards will process the SALE but will not return a recurring_token.Go-Live Checklist#
Complete these items before requesting production credentials.
Technical
| Item | Detail |
|---|---|
| ✅ SALE tested — success | Card 4111111111111111 exp 01/2038 returns SUCCESS/SETTLED |
| ✅ SALE tested — decline | Exp 02/2038 returns DECLINED |
| ✅ 3DS redirect handled | Exp 05/2038 → redirect → return → SUCCESS. Exp 06/2038 → DECLINED |
| ✅ Callback handler implemented | Endpoint returns plain OK. Hash verified using Formula 2. Tested with all result types. |
| ✅ CREDITVOID tested | Full and partial refunds work correctly |
| ✅ VOID tested (if used) | Same-day cancellation on SETTLED transaction |
| ✅ GET_TRANS_STATUS tested | Status polling works as fallback when callback delayed |
| ✅ Error handling implemented | All error codes handled gracefully. User sees meaningful messages. |
| ✅ Idempotent order IDs | Each payment attempt uses a unique order_id. Duplicates handled. |
| ✅ IP addresses provided | Production server IPs sent to CentaPay for whitelisting |
| ✅ Callback URL configured | Production callback URL registered with CentaPay |
| ✅ HTTPS everywhere | All endpoints use TLS. No plain HTTP. |
If Using Recurring
| Item | Detail |
|---|---|
| ✅ RECURRING_SALE tested | Initial SALE with recurring_init=Y, then RECURRING_SALE with token |
| ✅ RETRY tested | Soft decline → RETRY → final result via callback |
| ✅ Schedule ops tested (if used) | CREATE, PAUSE, RUN, DELETE, SCHEDULE_INFO, DESCHEDULE |
If Using Payouts
| Item | Detail |
|---|---|
| ✅ CREDIT2CARD tested | Test card 4601541833776519 returns SUCCESS |
| ✅ Formula 5 hash verified | Request hash uses Formula 5 (not Formula 1) |
| ✅ Formula 6 callback hash | Callback verification uses Formula 6 (not Formula 2) |
If Using Digital Wallets
| Item | Detail |
|---|---|
| ✅ Apple Pay: Merchant ID configured | Certificates and keys uploaded to admin panel |
| ✅ Apple Pay: Domains verified | All payment domains registered in Apple Developer |
| ✅ Google Pay: Integration checklist | Completed per Google's requirements |
| ✅ Google Pay: Domains verified | Verified in Google Business Console |
| ✅ Formula 8 hash used | Wallet SALE uses email + PASSWORD only |
Compliance
| Item | Detail |
|---|---|
| ✅ PCI DSS evidence | SAQ D or full assessment (for raw card S2S). Reduced scope for wallet-only. |
| ✅ KYB complete | Business verification documents submitted and approved |
| ✅ Prohibited MCCs reviewed | Business model confirmed against prohibited categories |
| ✅ Client agreement signed | Executed with CentaPay |
Commercial
| Item | Detail |
|---|---|
| ✅ Production credentials received | Separate CLIENT_KEY, PASSWORD, PAYMENT_URL for production |
| ✅ Settlement currency confirmed | USD or preferred currency agreed with CentaPay |
| ✅ MID configured | Production MID mapped to your account by CentaPay ops |
Contact [email protected] when all items are complete to begin the go-live process.