Orders
createPayment and createPayout are the two write calls. Both take the business fields of the API Reference request body, seal and sign the request, and return the created order. The field set per country and method is in the API Reference: open Payments or Payouts, then choose the country and method.
Request shape
| Field | Required | Notes |
|---|---|---|
merchantOrderNo | yes | Your unique number for this order. The only key that prevents a duplicate order, see Idempotency. |
currency | yes | ISO 4217, upper case. |
amount | yes | Decimal string, greater than zero, at most 16 integer digits and 2 decimals, e.g. "100.00". |
paymentMethod / payoutMethod | yes | code plus at most one extra object named after the code in lowerCamelCase: PIX → pix, PK_JAZZCASH → pkJazzcash. |
webhookUrl | yes | Absolute https:// URL that receives the final state. |
country | no | ISO 3166 alpha-2. Required only when the currency is ambiguous. |
returnUrl | payments only | Where the hosted checkout sends the payer back. |
attach | no | Opaque merchant data, returned unchanged in queries and webhooks. |
Create a payment
- Go
- JavaScript
- Python
- PHP
- Java
order, err := c.CreatePayment(ctx, &deepayment.CreatePaymentReq{
MerchantOrderNo: "M202605060001",
Currency: deepayment.CurrencyBRL,
Amount: "250.00",
PaymentMethod: deepayment.PaymentMethod{
Code: deepayment.MethodCodePIX,
Pix: &deepayment.PaymentPixExtra{PayerCPF: "12345678901", PayerName: "Joao Silva"},
},
ReturnUrl: "https://merchant.example/return",
WebhookUrl: "https://merchant.example/webhook/payment",
Attach: "user_123",
})
if err != nil { /* see Errors */ }
redirect(order.Action.Url) // or render order.Action.QrCode / order.Action.PayContent
Go exposes a typed struct per method extra (PaymentPixExtra, PaymentPkWalletExtra, ...). For a method that is not in your SDK version yet, set the extra by name:
m := deepayment.PaymentMethod{Code: "NEW_METHOD"}
_ = m.SetExtra("newMethod", map[string]any{"customerName": "X", "bankCode": "001"})
const order = await client.createPayment({
merchantOrderNo: 'M202605060001',
currency: 'BRL',
amount: '250.00',
paymentMethod: { code: 'PIX', pix: { payerCPF: '12345678901', payerName: 'Joao Silva' } },
returnUrl: 'https://merchant.example/return',
webhookUrl: 'https://merchant.example/webhook/payment',
attach: 'user_123',
});
redirect(order.action?.url); // or render order.action?.qrCode / order.action?.payContent
from deepayment import CreatePaymentReq
order = client.create_payment(CreatePaymentReq(
merchantOrderNo="M202605060001",
currency="BRL",
amount="250.00",
paymentMethod={"code": "PIX", "pix": {"payerCPF": "12345678901", "payerName": "Joao Silva"}},
returnUrl="https://merchant.example/return",
webhookUrl="https://merchant.example/webhook/payment",
attach="user_123",
))
redirect(order.action.url) # or render order.action.qrCode / order.action.payContent
CreatePaymentReq and CreatePayoutReq are dataclasses; paymentMethod / payoutMethod are plain dicts. Responses are dataclasses with the API field names (order.orderNo, order.action.url).
$order = $client->createPayment([
'merchantOrderNo' => 'M202605060001',
'currency' => 'BRL',
'amount' => '250.00',
'paymentMethod' => ['code' => 'PIX', 'pix' => ['payerCPF' => '12345678901', 'payerName' => 'Joao Silva']],
'returnUrl' => 'https://merchant.example/return',
'webhookUrl' => 'https://merchant.example/webhook/payment',
'attach' => 'user_123',
]);
redirect($order['action']['url'] ?? ''); // or render $order['action']['qrCode'] / ['payContent']
Requests and responses are associative arrays with the API field names.
Map<String, Object> order = client.createPayment(Map.of(
"merchantOrderNo", "M202605060001",
"currency", "BRL",
"amount", "250.00",
"paymentMethod", Map.of("code", "PIX",
"pix", Map.of("payerCPF", "12345678901", "payerName", "Joao Silva")),
"returnUrl", "https://merchant.example/return",
"webhookUrl", "https://merchant.example/webhook/payment",
"attach", "user_123"));
Map<String, Object> action = (Map<String, Object>) order.get("action");
redirect((String) action.get("url")); // or render action.get("qrCode") / action.get("payContent")
Requests and responses are Map<String, Object> with the API field names.
Create a payout
Same call shape with createPayout and a payoutMethod object. Payout extras carry the recipient account; every field the gateway requires for that currency is checked locally before sending.
- Go
- JavaScript
- Python
- PHP
- Java
order, err := c.CreatePayout(ctx, &deepayment.CreatePayoutReq{
MerchantOrderNo: "P202605060001",
Currency: deepayment.CurrencyBRL,
Amount: "1000.00",
PayoutMethod: deepayment.PayoutMethod{
Code: deepayment.MethodCodePIX,
Pix: &deepayment.PayoutPixExtra{KeyType: "CPF", Key: "12345678901"},
},
WebhookUrl: "https://merchant.example/webhook/payout",
})
const order = await client.createPayout({
merchantOrderNo: 'P202605060001',
currency: 'BRL',
amount: '1000.00',
payoutMethod: { code: 'PIX', pix: { keyType: 'CPF', key: '12345678901' } },
webhookUrl: 'https://merchant.example/webhook/payout',
});
order = client.create_payout(CreatePayoutReq(
merchantOrderNo="P202605060001",
currency="BRL",
amount="1000.00",
payoutMethod={"code": "PIX", "pix": {"keyType": "CPF", "key": "12345678901"}},
webhookUrl="https://merchant.example/webhook/payout",
))
$order = $client->createPayout([
'merchantOrderNo' => 'P202605060001',
'currency' => 'BRL',
'amount' => '1000.00',
'payoutMethod' => ['code' => 'PIX', 'pix' => ['keyType' => 'CPF', 'key' => '12345678901']],
'webhookUrl' => 'https://merchant.example/webhook/payout',
]);
Map<String, Object> order = client.createPayout(Map.of(
"merchantOrderNo", "P202605060001",
"currency", "BRL",
"amount", "1000.00",
"payoutMethod", Map.of("code", "PIX", "pix", Map.of("keyType", "CPF", "key", "12345678901")),
"webhookUrl", "https://merchant.example/webhook/payout"));
A payout moves funds. Read Errors before going live: a transport error on a payout must never be treated as a failure.
The order object
Both calls and the query calls return the same object.
| Field | Meaning |
|---|---|
orderNo | Platform order number. Use it in queries and receipts. |
merchantOrderNo | Your number, echoed. |
status | PENDING, PROCESSING, SUCCEEDED, FAILED, EXPIRED, CANCELED. See Order Status. |
amount, paidAmount | Decimal strings. paidAmount is what actually settled; for range-amount methods it can differ from amount. |
paymentMethod / payoutMethod | The method code as a string. |
action.url | Hosted checkout or channel page to send the payer to. |
action.payContent, action.qrCode | Content for a checkout you render yourself; format per method page. |
failure | Present when status is FAILED: code, msg, message. Branch on msg. |
attach | Echoed. |
createdAt, updatedAt | Unix milliseconds. |
Local validation
Before signing, the SDK checks the request and raises a request error (Go: errors.Is(err, ErrInvalidRequest)) if any of these fail. Nothing is sent.
| Check | Rule |
|---|---|
| Required fields | merchantOrderNo, currency, amount, webhookUrl non-blank. |
amount | A string matching ^(0|[1-9][0-9]{0,15})(\.[0-9]{1,2})?$ and greater than zero. A JSON number is rejected. |
webhookUrl | Starts with https://. |
| Method shape | code non-blank; at most one extra object; the extra present must be the one that belongs to code; if the currency has a method allow-list, code must be on it. |
| Required extras | The fields the gateway requires for that currency, plus any a specific code adds (for example an INR payout needs ifsc and account only for IN_IFSC). |
Formats are deliberately not checked: phone length, e-mail, IFSC, document numbers and bank codes are validated by the gateway and reported as INVALID_FIELD. A currency the SDK does not know is not rejected; the gateway decides.
Idempotency and retries
merchantOrderNo is the only key that prevents a duplicate order. A second create with the same number never creates a second order: the platform returns the original order, or answers IDEMPOTENCY_CONFLICT when it recognises the number as taken but cannot return that order.
Two rules follow:
- After an unknown outcome (timeout, transport error, non-envelope response), never allocate a new
merchantOrderNo. Query the existing one, or resend the identical request under the same number. - A resend must carry identical parameters. The platform returns the original order without comparing fields, so a changed amount or account silently has no effect. To change anything, use a new
merchantOrderNoand reconcile the original order first.
The SDK does not retry on its own. Each call generates a fresh nonce and signature, so calling the method again is a valid retry while replaying captured bytes is not.
An optional idempotency key can be attached to a create call. It is carried in the Idempotency-Key header for tracing and correlation; it is not a deduplication key.
- Go
- JavaScript
- Python
- PHP
- Java
order, err := c.CreatePayment(ctx, req, deepayment.WithIdempotencyKey(key)) // key: UUID v4
await client.createPayment(req, { idempotencyKey: key });
client.create_payment(req, idempotency_key=key)
$client->createPayment($req, $key);
client.createPayment(req, key);
When omitted the SDK generates one. A supplied key must be a UUID v4.
Actual payer details
Signed GET /api/v1/payments requests, by platform or merchant order number, and payment webhooks can return:
{"payer":{"name":"Maria Silva","documentNumber":"01234567890"}}
These details come from the payment channel, not the name or CPF submitted when creating the order. Unavailable fields are omitted; payer is omitted when both fields are unavailable. Document numbers remain strings, including leading zeros; no document type is inferred.
Payment queries require merchant signature authentication and order ownership checks. Payment webhooks deliver the same optional object to the order’s webhook URL; verify the platform signature before using it. Creation responses, public checkout, ordinary payout queries and payout webhooks do not include this object. Use HTTPS with certificate verification; redact names and document numbers when logging on your side. Query responses and webhook bodies are ordinary JSON without additional body encryption.
Webhook bodies are fixed when the notification event is first created and stay unchanged on retries. Previously generated notifications are not backfilled with payer details; use the authenticated payment query to retrieve available details.