Integration rules
Rules for the three v1 contracts: first what holds on all of them, then what each one adds. v2 has its own rules — switch the version selector to v2.
Every v1 contract
- HTTP 2xx is not a final outcome. Read the status field. On payouts a validation failure is even returned as HTTP 200 — the outcome is inside the XML body.
- Only a final status is an outcome. The final set differs per contract; see the table below. Never treat a non-terminal value as success.
- A timeout tells you nothing. It does not mean failure, it does not cancel anything. Retry the identical request; never create a replacement transaction.
- Your own reference is unique.
merchant_transaction_id(Apple Pay, Google Pay),reference(card payments) andid(payouts) identify one business transaction. Generate it once, persist it before you call. - An unknown status leaves the transaction unresolved. Keep polling, keep accepting callbacks, do not decide it failed.
- Sign the exact bytes. Re-serializing, pretty-printing, or sorting keys changes the signature.
- Callback handlers are idempotent. Deliveries can repeat on every contract. Do not rely on their order.
- A callback is a notification, not proof. Re-read the transaction before releasing goods or crediting an account.
Final statuses by contract
Pay-ins are one area with three methods, but not one contract: Apple Pay and Google Pay share a status vocabulary, card payments have their own, and payouts a third.
| Contract | Not final | Final |
|---|---|---|
| Pay-ins — Apple Pay, Google Pay | pending (deprecated: order_scheduled, redirect_pending) |
paid, order_failed, refunded |
| Pay-ins — card payments | 0, 1, 8, 15 |
3 paid, 4 refunded, 98 expired, 99 failed |
| Payouts | OK, PROCESSING |
PAID, NOT_PAID, ERROR |
OK on a payout means accepted for processing, not completed. The result arrives later, by callback or check.
Pay-ins — Apple Pay and Google Pay
- Two headers:
Sdk-Partner-Token(service_id:secret) andX-Signature. X-Signatureis HMAC-SHA256 of the compact JSON body, keyed with your Sign Key, lowercase hex. Sign the field order you transmit; sorting the keys produces a different signature. Keepnullvalues in the signed payload.GETrequests carry no body and need onlySdk-Partner-Token.- When a create or
GET /sdk-partner/alternative-mobile-pay/mobile-pay/{id}/statusresponse carriesredirect_data, send the buyer toredirect_data.url— in any non-final status. Some payments start only after the buyer opens it and endorder_failedafter 10 minutes without it. The buyer returning is not confirmation. - Poll
GET /sdk-partner/alternative-mobile-pay/mobile-pay/{id}/statusfrom 5 seconds after the create until the status is final. A webhook can bring the result sooner; delivery can be delayed. - Replay the same
merchant_refund_idto make a refund idempotent.
Pay-ins — card payments
- Credentials are
api_keyandsecret_key, issued separately from the Apple Pay and Google Pay ones. They do not authenticate against each other. - Every request carries two fields:
data, the request JSON base64-encoded, andsign, its signature.api_keygoes inside the encodeddata, not beside it. signishash_hmacwith the MD5 algorithm over the base64 string, keyed withsecret_key. Sign the encoded string, not the JSON before encoding.- Verify
signon callbacks the same way before trusting the payload. statusis an integer, not a string.1is authorization — funds locked, not taken. The payment is complete at3.8means the provider had a temporary problem and returns a payment form link to redirect the payer to. It is not a failure.15means a refund is still processing, which can take 1–7 days.
Payouts
hashis MD5 of specific fields concatenated with no delimiter, plussecret_key. The field set differs per endpoint. Empty fields are skipped silently, which is why a wrong hash usually means a field you left blank.- Responses are XML even when the request was JSON.
- Repeating an
idreturns the existing payout with its current status. There is no check that the body matches, so a retry with a changed amount silently returns the old payout. Never change the body on retry. - Callbacks are form-urlencoded POST with
RESULT1/0 and an MD5HASH. Up to 15 retries over about two days. - Reconcile with
checkwhen a callback is lost.