Payments API for partners

Process payments for your merchants with Outpost as merchant of record. Send the payment with the order and customer details, and Outpost processes it on its own payment accounts, issues the receipt or invoice, and handles the tax. This API doesn't return those documents.

Amounts are tax-inclusive: submit the total the shopper sees at checkout.

Because Outpost is the seller, the merchant must add the seller disclosure to its checkout; the API doesn't return disclosure text.

EndpointPurpose
POST /api/paymentsCreate and process a payment
GET /api/payments/{paymentId}Retrieve a payment
POST /api/payments/{paymentId}/cancelCancel one pending Pix Automático charge
GET /api/pix-authorisations/{pixAuthorisationId}Retrieve a Pix Automático authorisation
POST /api/pix-authorisations/{pixAuthorisationId}/cancelCancel a Pix Automático authorisation
POST /api/payments/{paymentId}/refundsRefund a payment, in full or in part
POST /api/webhooksRegister a webhook endpoint for a merchant

Payment flow

Authentication

Requests use the merchant's own Outpost credentials. When a merchant enables Outpost in your platform, they enter the Client ID and Client Secret from their Outpost dashboard. Exchange them for an access token with the OAuth 2.0 client_credentials grant, sending them as client_id and client_secret. Each token acts for that merchant. The response returns access_token and expires_in in seconds; request a new token before it expires.

Authorization: Bearer <your_access_token>

Authentication

curl -X POST \
  "https://access.outpostanywhere.com/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$MERCHANT_CLIENT_ID" \
  -d "client_secret=$MERCHANT_CLIENT_SECRET" | jq

Conventions

TopicRule
Base URLhttps://api.outpostanywhere.com
FormatJSON over HTTPS, camelCase field names
AmountsAn object of amount, a decimal string (for example "120.99"), and an ISO 4217 currency
CountriesISO 3166-1 alpha-2, uppercase
IDsPayment, refund and Pix authorisation IDs are UUIDs
IdempotencyEvery POST requires an Idempotency-Key header of at most 255 characters. Retrying with the same key and a byte-identical body returns the resource the first request created, in its current state; the same key with a different body returns 422 idempotency_key_reused. Keys are scoped to the merchant and stay used permanently once a request succeeds: use a new key for each new payment or refund

Create payment

POST/api/payments

Processes a payment for the tax-inclusive total of an order. To retry a failed payment, create a new payment with a new Idempotency-Key; it can keep the same merchantReference.

Request Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringYesUnique key for this request. See Conventions

Request Body Parameters

ParameterTypeRequiredDescription
merchantReferencestringYesYour order or transaction reference. Can be reused across attempts; each attempt gets its own payment ID
amountobjectYesTax-inclusive total: amount (decimal string) and currency (ISO 4217), equal to the sum of the line items. Must be BRL when the billing country is BR. "0.00" only for a card verification
customer.merchantCustomerReferencestringYour customer ID. Must stay the same for a customer and must not contain personal data
customer.firstNamestringYesShopper first name
customer.lastNamestringYesShopper last name
customer.emailstringYesFor the receipt or invoice
customer.billingAddressobjectYesline1, line2, city, state, postalCode, country. country is always required; outside the EU, line1, city and postalCode are too, and US and CA addresses need a two-letter state
customer.shippingAddressobjectThe same fields and rules as billingAddress
customer.taxIdentifiers[]arraytype (BR_CPF, BR_CNPJ, EU_VAT, GB_VAT, US_EIN) and code. Outpost checks CPF and CNPJ check digits
lineItems[]arrayYesmerchantLineItemReference, productCode (your own SKU; defaults to merchantLineItemReference), description, productType, unitPrice (tax-inclusive decimal string), quantity
lineItems[].productTypestringYesPHYSICAL, DIGITAL or SERVICES (a fee on a goods order). An order with a SERVICES line needs at least one PHYSICAL line priced above zero, or Outpost returns 400 invalid_argument. A service sold on its own is DIGITAL
lineItems[].ancillaryTypestringCOMMISSION, SHIPPING_COST, HANDLING, PACKAGING or OTHER
evidence.ipAddressstringThe shopper's IP address
paymentMethod.typestringYesHow the shopper pays. See the payment method types below
returnUrlstringWhere the shopper returns after a 3-D Secure challenge or bank redirect
metadataobjectNoString key-value pairs, returned on the payment and its webhooks

Payment method types

Each method adds its own fields, described in its section.

paymentMethod.typeMeaning
cardA card number or network token, including decrypted Apple Pay and Google Pay tokens. Outpost runs 3-D Secure when the shopper is present
idealOutpost returns a bank redirect
pixOutpost returns a QR code. Add pixAutomatico to enrol a recurring authorisation
pixAutomaticoCharges an ACTIVE Pix Automático authorisation on billingDate

Response 201 Created · captured

{
  "id": "01a182d1-82b8-7b18-bf89-08ff16b3fbfd",
  "merchantReference": "order-1042",
  "status": "CAPTURED",
  "amount": { "amount": "120.99", "currency": "EUR" },
  "paymentMethod": { "type": "card", "brand": "visa", "last4": "1111" },
  "createdAt": "2026-10-28T14:02:11Z",
  "capturedAt": "2026-10-28T14:02:12Z",
  "metadata": {}
}

Response 201 Created · failed

failure says why the payment failed. See Payment failures for its fields and codes.

{
  "id": "01a1830f-a8e0-7448-bd72-c4d4d3dd8e1b",
  "merchantReference": "order-1043",
  "status": "FAILED",
  "amount": { "amount": "120.99", "currency": "EUR" },
  "paymentMethod": { "type": "card", "brand": "visa", "last4": "1111" },
  "failure": {
    "code": "card_declined",
    "message": "The card was declined by the issuer.",
    "declineCode": "05",
    "retryable": false
  },
  "createdAt": "2026-10-28T15:10:04Z",
  "failedAt": "2026-10-28T15:10:05Z",
  "metadata": {}
}

Code Example

curl -X POST \
  "https://api.outpostanywhere.com/api/payments" \
  -H "Authorization: Bearer $OUTPOST_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "merchantReference": "order-1042",
    "amount": { "amount": "120.99", "currency": "EUR" },
    "customer": {
      "merchantCustomerReference": "CUST-001",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john.doe@example.com",
      "billingAddress": {
        "line1": "Keizersgracht 123",
        "city": "Amsterdam",
        "postalCode": "1015 CJ",
        "country": "NL"
      }
    },
    "lineItems": [
      {
        "merchantLineItemReference": "ITEM-001",
        "productCode": "SKU-123",
        "description": "Design course, lifetime access",
        "productType": "DIGITAL",
        "unitPrice": "120.99",
        "quantity": 1
      }
    ],
    "evidence": { "ipAddress": "185.23.108.42" },
    "browserInfo": {
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15",
      "acceptHeader": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
      "language": "nl-NL",
      "colorDepth": 24,
      "screenHeight": 900,
      "screenWidth": 1440,
      "timeZoneOffset": -60,
      "javaEnabled": false,
      "javaScriptEnabled": true
    },
    "paymentMethod": {
      "type": "card",
      "card": {
        "number": "4111111111111111",
        "cvc": "737",
        "expiryMonth": "03",
        "expiryYear": "2030",
        "holderName": "John Doe"
      }
    },
    "returnUrl": "https://checkout.example.com/return"
  }' | jq

This example is a card payment; see Cards for paymentMethod.card and browserInfo. Responses carry the fields listed under Get payment.

Get payment

GET/api/payments/{paymentId}

Returns the payment's current state, with the fields below. Use it to confirm a result when the shopper returns from a redirect. If a create request times out, you have no payment ID: retry it with the same Idempotency-Key.

Path Parameters

ParameterTypeRequiredDescription
paymentIdstringYesOutpost payment ID (UUID)

Response 200 OK

{
  "id": "01a182d1-82b8-7b18-bf89-08ff16b3fbfd",
  "merchantReference": "order-1042",
  "status": "CAPTURED",
  "amount": { "amount": "120.99", "currency": "EUR" },
  "paymentMethod": { "type": "card", "brand": "visa", "last4": "1111" },
  "createdAt": "2026-10-28T14:02:11Z",
  "capturedAt": "2026-10-28T14:02:12Z",
  "metadata": {}
}

Response Fields

ParameterTypeRequiredDescription
idstring-Outpost payment ID (UUID)
merchantReferencestring-As sent
statusstring-PENDING, REQUIRES_ACTION, CAPTURED, FAILED or CANCELED. See Payment status. New values may be added
amountobject-As sent
paymentMethod.typestring-As sent
paymentMethod.brandstring-card only: visa, mastercard, amex, elo or hipercard. New values may be added
paymentMethod.last4string-card only: the last four digits of the card number, or of the network token
paymentMethod.networkTransactionIdstring-On a CAPTURED payment with recurring.initiator CUSTOMER, in this response and on GET. After a 3-D Secure challenge, fetch it with GET when payment.captured arrives. Send it on later charges
paymentMethod.recurringobject-As sent, without networkTransactionId
paymentMethod.pixAuthorisationIdstring-pixAutomatico charges only
paymentMethod.billingDatestring-pixAutomatico charges only
pixAuthorisationobject-Pix Automático enrolment payments only: id and status of the authorisation it created
actionobject-REQUIRES_ACTION only. type REDIRECT, with url (open it with GET), or QR_CODE, with qrCodeData. expiresAt: when the step lapses and the payment fails
failureobject-FAILED only. See Payment failures
createdAt, capturedAt, failedAt, canceledAtstring-ISO 8601 timestamps. capturedAt, failedAt and canceledAt appear once the payment has that status
metadataobject-As sent

Code Example

curl "https://api.outpostanywhere.com/api/payments/$PAYMENT_ID" \
  -H "Authorization: Bearer $OUTPOST_ACCESS_TOKEN" | jq

Cards

Send paymentMethod.type card with the card details, or with card.networkToken for a network token or decrypted Apple Pay or Google Pay token. Send card details as you do to other providers, directly or through your card vault's forward proxy; card data is encrypted on receipt.

Card Fields

ParameterTypeRequiredDescription
paymentMethod.cardobjectThe card details: number, cvc, expiry and holderName, or a networkToken object instead of the number and expiry
paymentMethod.card.numberstringCard number (PAN), 12 to 19 digits, no spaces or separators
paymentMethod.card.cvcstringNoCard security code, 3 or 4 digits. Send it whenever you have it; omit it when you don't, for example for a Google Pay card number, and always on charges with recurring.initiator MERCHANT
paymentMethod.card.expiryMonthstringTwo digits, 01 to 12 (e.g., "03")
paymentMethod.card.expiryYearstringFour digits (e.g., "2030")
paymentMethod.card.holderNamestringName as printed on the card, at most 255 characters
paymentMethod.installmentsintegerNoMonthly instalments the shopper chose, 2 to 12, for BRL card payments above zero. When omitted, the shopper pays in one instalment
browserInfoobjectThe EMV 3-D Secure browser fields from the shopper's browser: userAgent, acceptHeader, language, colorDepth, screenHeight, screenWidth, timeZoneOffset, javaEnabled and javaScriptEnabled

Response 201 Created · 3-D Secure

Send the shopper to action.url. They return to your returnUrl; the result follows as a webhook.

{
  "id": "01a182f4-7020-72c6-aba3-26b4604bcb4e",
  "merchantReference": "order-1044",
  "status": "REQUIRES_ACTION",
  "amount": { "amount": "120.99", "currency": "EUR" },
  "paymentMethod": { "type": "card", "brand": "visa", "last4": "1111" },
  "action": {
    "type": "REDIRECT",
    "url": "https://acs.issuer.example/challenge/7f3a9c...",
    "expiresAt": "2026-10-28T14:55:20Z"
  },
  "createdAt": "2026-10-28T14:40:20Z",
  "metadata": {}
}

Apple Pay, Google Pay and network tokens

  • You decrypt wallet payloads with your own Apple Pay merchant ID and certificate, and your own Google Pay setup. Outpost doesn't decrypt them.
  • When Google Pay returns a card number instead of a token, send it as type card; 3-D Secure applies as for any card.

Network Token Fields

ParameterTypeRequiredDescription
paymentMethod.card.networkTokenobjectNoThe network token or decrypted wallet token. Fields below
paymentMethod.card.networkToken.tokenstringToken number, 13 to 19 digits
paymentMethod.card.networkToken.expiryMonthstringToken expiry month, two digits (e.g., "03")
paymentMethod.card.networkToken.expiryYearstringToken expiry year, four digits (e.g., "2030")
paymentMethod.card.networkToken.cryptogramstringBase64 cryptogram from the network or wallet, as you received it
paymentMethod.card.networkToken.ecistringElectronic Commerce Indicator, two digits (e.g., "05")
paymentMethod.card.networkToken.sourcestringAPPLE_PAY or GOOGLE_PAY: a wallet token you decrypted; Outpost skips 3-D Secure. NETWORK_TOKEN: a token you provisioned with Visa or Mastercard; also send browserInfo and returnUrl, as for a card number; Outpost runs 3-D Secure as for card

Request Apple Pay

{
  "merchantReference": "order-3301",
  "amount": { "amount": "54.00", "currency": "EUR" },
  "customer": {
    "merchantCustomerReference": "CUST-3301",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "billingAddress": {
      "line1": "Keizersgracht 123",
      "city": "Amsterdam",
      "postalCode": "1015 CJ",
      "country": "NL"
    },
    "shippingAddress": {
      "line1": "Keizersgracht 123",
      "city": "Amsterdam",
      "postalCode": "1015 CJ",
      "country": "NL"
    }
  },
  "lineItems": [
    {
      "merchantLineItemReference": "ITEM-001",
      "productCode": "SKU-BAG",
      "description": "Leather tote bag",
      "productType": "PHYSICAL",
      "unitPrice": "54.00",
      "quantity": 1
    }
  ],
  "evidence": { "ipAddress": "185.23.108.42" },
  "paymentMethod": {
    "type": "card",
    "card": {
      "holderName": "John Doe",
      "networkToken": {
        "token": "4895370012003478",
        "expiryMonth": "12",
        "expiryYear": "2029",
        "cryptogram": "AgAAAAAABk4DWZ4C28yUQAAAAAA=",
        "eci": "05",
        "source": "APPLE_PAY"
      }
    }
  }
}

Recurring card payments

Send paymentMethod.recurring on the first payment, with the shopper present, and on every later charge. You keep the card details and the networkTransactionId Outpost returns.

Recurring Fields

ParameterTypeRequiredDescription
paymentMethod.recurringobjectNoMarks a card payment as part of a recurring series. Send it on the first payment and on every later charge. When omitted, the payment is a one-off.
paymentMethod.recurring.initiatorstringWho starts the payment: CUSTOMER or MERCHANT. See the table below
paymentMethod.recurring.typestringSUBSCRIPTION: charges on a fixed schedule for a fixed or known amount. UNSCHEDULED: charges at varying times or amounts, for example top-ups or usage billing. Send the same value on every payment in the series
paymentMethod.recurring.networkTransactionIdstringLinks the charge to the payment the shopper agreed to. A new card number, a switch to a network token, or a subscription moved from another provider needs a new CUSTOMER payment
paymentMethod.recurring.initiatorMeaning
CUSTOMERThe first payment, with the shopper present. Outpost runs 3-D Secure (not for Apple Pay or Google Pay) and returns networkTransactionId. Send amount "0.00" to verify the card without charging it; Outpost issues no receipt
MERCHANTEvery later charge. No shopper step: the result is CAPTURED or FAILED

Response 201 Created · first recurring card payment

Store paymentMethod.networkTransactionId with the card and send it on each later charge.

{
  "id": "01a19c91-4eb8-7994-b099-3e4b67d564f6",
  "merchantReference": "sub-2210-2026-11",
  "status": "CAPTURED",
  "amount": { "amount": "19.99", "currency": "EUR" },
  "paymentMethod": {
    "type": "card",
    "brand": "visa",
    "last4": "1111",
    "networkTransactionId": "581234567890123",
    "recurring": { "initiator": "CUSTOMER", "type": "SUBSCRIPTION" }
  },
  "createdAt": "2026-11-02T14:02:11Z",
  "capturedAt": "2026-11-02T14:02:12Z",
  "metadata": {}
}

Request later charge

No cvc, browserInfo, returnUrl or evidence.

{
  "merchantReference": "sub-2210-2026-12",
  "amount": { "amount": "19.99", "currency": "EUR" },
  "customer": {
    "merchantCustomerReference": "CUST-2210",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "billingAddress": {
      "line1": "Keizersgracht 123",
      "city": "Amsterdam",
      "postalCode": "1015 CJ",
      "country": "NL"
    }
  },
  "lineItems": [
    {
      "merchantLineItemReference": "PLAN-MONTHLY",
      "productCode": "SKU-PLAN-M",
      "description": "Design app, monthly plan",
      "productType": "DIGITAL",
      "unitPrice": "19.99",
      "quantity": 1
    }
  ],
  "paymentMethod": {
    "type": "card",
    "card": {
      "number": "4111111111111111",
      "expiryMonth": "03",
      "expiryYear": "2030",
      "holderName": "John Doe"
    },
    "recurring": {
      "initiator": "MERCHANT",
      "type": "SUBSCRIPTION",
      "networkTransactionId": "581234567890123"
    }
  }
}

Request zero-amount card verification

Verifies and saves a card without charging it: one "0.00" line item and recurring.initiator CUSTOMER. installments doesn't apply. The response is CAPTURED with a zero amount and a networkTransactionId, or REQUIRES_ACTION for 3-D Secure.

{
  "merchantReference": "card-setup-2210",
  "amount": { "amount": "0.00", "currency": "EUR" },
  "customer": {
    "merchantCustomerReference": "CUST-2210",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "billingAddress": {
      "line1": "Keizersgracht 123",
      "city": "Amsterdam",
      "postalCode": "1015 CJ",
      "country": "NL"
    }
  },
  "lineItems": [
    {
      "merchantLineItemReference": "PLAN-MONTHLY",
      "productCode": "SKU-PLAN-M",
      "description": "Design app, monthly plan (card verification)",
      "productType": "DIGITAL",
      "unitPrice": "0.00",
      "quantity": 1
    }
  ],
  "evidence": { "ipAddress": "185.23.108.42" },
  "paymentMethod": {
    "type": "card",
    "card": {
      "number": "4111111111111111",
      "cvc": "737",
      "expiryMonth": "03",
      "expiryYear": "2030",
      "holderName": "John Doe"
    },
    "recurring": { "initiator": "CUSTOMER", "type": "SUBSCRIPTION" }
  },
  "browserInfo": {
    "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15",
    "acceptHeader": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "language": "nl-NL",
    "colorDepth": 24,
    "screenHeight": 900,
    "screenWidth": 1440,
    "timeZoneOffset": -60,
    "javaEnabled": false,
    "javaScriptEnabled": true
  },
  "returnUrl": "https://checkout.example.com/return"
}

iDEAL

Send paymentMethod.type ideal with an amount in EUR and a returnUrl. iDEAL takes no other method fields.

Request iDEAL

{
  "merchantReference": "order-3488",
  "amount": { "amount": "39.00", "currency": "EUR" },
  "customer": {
    "merchantCustomerReference": "CUST-3488",
    "firstName": "Sanne",
    "lastName": "de Vries",
    "email": "sanne.devries@example.com",
    "billingAddress": {
      "line1": "Oudegracht 120",
      "city": "Utrecht",
      "postalCode": "3511 AX",
      "country": "NL"
    }
  },
  "lineItems": [
    {
      "merchantLineItemReference": "EBOOK-01",
      "productCode": "SKU-EBOOK-01",
      "description": "Cookbook, ebook edition",
      "productType": "DIGITAL",
      "unitPrice": "39.00",
      "quantity": 1
    }
  ],
  "evidence": { "ipAddress": "185.23.108.42" },
  "paymentMethod": { "type": "ideal" },
  "returnUrl": "https://checkout.example.com/return"
}

Response 201 Created · bank redirect

Send the shopper to action.url to approve the payment in their bank. They return to your returnUrl; the result follows as a webhook. If they don't finish before action.expiresAt, the payment fails with authentication_failed.

{
  "id": "01a18c7f-d008-7d21-9e3a-6f4b2c8d1a57",
  "merchantReference": "order-3488",
  "status": "REQUIRES_ACTION",
  "amount": { "amount": "39.00", "currency": "EUR" },
  "paymentMethod": { "type": "ideal" },
  "action": {
    "type": "REDIRECT",
    "url": "https://ideal.example-bank.nl/pay/9c2f41...",
    "expiresAt": "2026-10-30T11:24:09Z"
  },
  "createdAt": "2026-10-30T11:09:09Z",
  "metadata": {}
}

Pix

Send paymentMethod.type pix with an amount in BRL and the shopper's CPF or CNPJ in customer.taxIdentifiers[]. Pix has no redirect, so there is no returnUrl. For recurring Pix, see Pix Automático.

Request Pix

{
  "merchantReference": "order-2077",
  "amount": { "amount": "309.47", "currency": "BRL" },
  "customer": {
    "merchantCustomerReference": "CUST-5120",
    "firstName": "Bruno",
    "lastName": "Lima",
    "email": "bruno.lima@example.com",
    "billingAddress": {
      "line1": "Avenida Paulista 1000",
      "city": "São Paulo",
      "state": "SP",
      "postalCode": "01310-100",
      "country": "BR"
    },
    "taxIdentifiers": [{ "type": "BR_CPF", "code": "12345678909" }]
  },
  "lineItems": [
    {
      "merchantLineItemReference": "COURSE-PRO",
      "productCode": "SKU-COURSE-PRO",
      "description": "Photography course, lifetime access",
      "productType": "DIGITAL",
      "unitPrice": "309.47",
      "quantity": 1
    }
  ],
  "evidence": { "ipAddress": "177.45.12.8" },
  "paymentMethod": { "type": "pix" }
}

Response 201 Created · Pix

Render action.qrCodeData as a QR code and offer it to copy. The QR code expires one hour after creation, at action.expiresAt; if the shopper hasn't paid by then, the payment fails with authentication_failed. The result follows as a webhook.

{
  "id": "01a18350-24b0-7373-9c9b-78d9b21f17fb",
  "merchantReference": "order-2077",
  "status": "REQUIRES_ACTION",
  "amount": { "amount": "309.47", "currency": "BRL" },
  "paymentMethod": { "type": "pix" },
  "action": {
    "type": "QR_CODE",
    "qrCodeData": "00020126580014br.gov.bcb.pix0136...",
    "expiresAt": "2026-10-28T17:20:30Z"
  },
  "createdAt": "2026-10-28T16:20:30Z",
  "metadata": {}
}

Pix Automático

Recurring Pix for subscriptions priced in BRL.

Enrol with the first payment

Create a payment with paymentMethod.type pix and a paymentMethod.pixAutomatico object. Outpost returns a QR code as for a one-off Pix payment. The shopper approves the first charge and the recurring authorisation together.

Pix Automático Fields

ParameterTypeRequiredDescription
paymentMethod.pixAutomaticoobjectNoEnrols a Pix Automático authorisation with this payment; the shopper approves both in one QR code
paymentMethod.pixAutomatico.amountTypestringFIXED or VARIABLE. See the table below
paymentMethod.pixAutomatico.recurringAmountstringThe amount every payment must equal, as a decimal string in BRL
paymentMethod.pixAutomatico.minAmountstringThe lowest amount a payment can be, as a decimal string in BRL
paymentMethod.pixAutomatico.frequencystringWEEKLY, MONTHLY, QUARTERLY, SEMIANNUAL or ANNUAL. Pix Automático has no daily cycle; Outpost returns 400 invalid_argument for any other value
paymentMethod.pixAutomatico.endsAtstringNoISO 8601, YYYY-MM-DD. Outpost charges no cycle after this date. When omitted, the authorisation runs until cancelled
paymentMethod.pixAutomatico.retryPolicybooleanNoWhether Outpost retries a failed debit; set once per authorisation. Defaults to true. See the table below
pixAutomatico.amountTypeMeaning
FIXEDEvery payment, including the enrolment, equals recurringAmount
VARIABLEEvery payment is at least minAmount. A charge above the shopper's bank-app ceiling fails with authorisation_amount_exceeded
pixAutomatico.retryPolicyMeaning
trueOutpost retries a failed debit up to three times within 7 days of billingDate, then sends one payment.captured or payment.failed
falseOutpost sends payment.failed on the first failed debit

Request enrolment

{
  "merchantReference": "sub-1042",
  "amount": { "amount": "49.90", "currency": "BRL" },
  "customer": {
    "merchantCustomerReference": "CUST-7781",
    "firstName": "Ana",
    "lastName": "Souza",
    "email": "ana.souza@example.com",
    "billingAddress": {
      "line1": "Rua Augusta 1500",
      "city": "São Paulo",
      "state": "SP",
      "postalCode": "01304-001",
      "country": "BR"
    },
    "taxIdentifiers": [{ "type": "BR_CPF", "code": "12345678909" }]
  },
  "lineItems": [
    {
      "merchantLineItemReference": "PLAN-MONTHLY",
      "productCode": "SKU-PLAN-M",
      "description": "Fitness app, monthly plan",
      "productType": "DIGITAL",
      "unitPrice": "49.90",
      "quantity": 1
    }
  ],
  "evidence": { "ipAddress": "177.45.12.8" },
  "paymentMethod": {
    "type": "pix",
    "pixAutomatico": {
      "amountType": "FIXED",
      "recurringAmount": "49.90",
      "frequency": "MONTHLY"
    }
  }
}

Response 201 Created · enrolment

{
  "id": "01a19c91-4eb8-7414-9330-f468f638178e",
  "merchantReference": "sub-1042",
  "status": "REQUIRES_ACTION",
  "amount": { "amount": "49.90", "currency": "BRL" },
  "paymentMethod": { "type": "pix" },
  "action": {
    "type": "QR_CODE",
    "qrCodeData": "00020101021226990014br.gov.bcb.pix2577...",
    "expiresAt": "2026-11-02T15:02:11Z"
  },
  "pixAuthorisation": {
    "id": "01a19c91-4eb8-7231-b916-d081927e245a",
    "status": "PENDING_APPROVAL"
  },
  "createdAt": "2026-11-02T14:02:11Z",
  "metadata": {}
}
  • The response is REQUIRES_ACTION with action.qrCodeData, which expires after one hour, and pixAuthorisation in PENDING_APPROVAL.
  • On approval, Outpost sends pix_authorisation.approved and payment.captured, the authorisation becomes ACTIVE, and startsAt is set to the approval date. The enrolment payment is the first cycle.
  • If the QR code expires, the authorisation becomes EXPIRED and the payment fails with authentication_failed.
  • If the shopper or their bank refuses, the authorisation becomes REJECTED and the payment fails with authorisation_rejected.

Response 200 OK · Get payment after approval

{
  "id": "01a19c91-4eb8-7414-9330-f468f638178e",
  "merchantReference": "sub-1042",
  "status": "CAPTURED",
  "amount": { "amount": "49.90", "currency": "BRL" },
  "paymentMethod": { "type": "pix" },
  "pixAuthorisation": {
    "id": "01a19c91-4eb8-7231-b916-d081927e245a",
    "status": "ACTIVE"
  },
  "createdAt": "2026-11-02T14:02:11Z",
  "capturedAt": "2026-11-02T14:05:40Z",
  "metadata": {}
}

Charge later cycles

  • Create a payment with paymentMethod.type pixAutomatico, pixAuthorisationId and billingDate, 2 to 10 days before the billing date.
  • billingDate falls on the authorisation's startsAt or a whole number of frequency cycles after it.
  • The response is PENDING. The result arrives as payment.captured or payment.failed on or after billingDate, after any retries, unless the charge or its authorisation is cancelled first.
  • The shopper's bank lets them cancel a single debit; it then fails with debit_canceled and the authorisation stays ACTIVE.
  • One charge per cycle: a second one returns 409 invalid_status unless the first is CANCELED. After a FAILED charge, create the next cycle's payment.
  • To stop or change one charge, cancel it.

Charge Fields

ParameterTypeRequiredDescription
paymentMethod.pixAuthorisationIdstringAn ACTIVE Pix Automático authorisation (UUID), from pix_authorisation.approved
paymentMethod.billingDatestringISO 8601, YYYY-MM-DD. The date the shopper's bank debits the account

Request charge

{
  "merchantReference": "sub-1042-2026-12",
  "amount": { "amount": "49.90", "currency": "BRL" },
  "customer": {
    "merchantCustomerReference": "CUST-7781",
    "firstName": "Ana",
    "lastName": "Souza",
    "email": "ana.souza@example.com",
    "billingAddress": {
      "line1": "Rua Augusta 1500",
      "city": "São Paulo",
      "state": "SP",
      "postalCode": "01304-001",
      "country": "BR"
    },
    "taxIdentifiers": [{ "type": "BR_CPF", "code": "12345678909" }]
  },
  "lineItems": [
    {
      "merchantLineItemReference": "PLAN-MONTHLY",
      "productCode": "SKU-PLAN-M",
      "description": "Fitness app, monthly plan",
      "productType": "DIGITAL",
      "unitPrice": "49.90",
      "quantity": 1
    }
  ],
  "paymentMethod": {
    "type": "pixAutomatico",
    "pixAuthorisationId": "01a19c91-4eb8-7231-b916-d081927e245a",
    "billingDate": "2026-12-02"
  }
}

Response 201 Created · charge

{
  "id": "01a211fa-92e0-7952-800d-54bf6e80d923",
  "merchantReference": "sub-1042-2026-12",
  "status": "PENDING",
  "amount": { "amount": "49.90", "currency": "BRL" },
  "paymentMethod": {
    "type": "pixAutomatico",
    "pixAuthorisationId": "01a19c91-4eb8-7231-b916-d081927e245a",
    "billingDate": "2026-12-02"
  },
  "createdAt": "2026-11-25T09:12:44Z",
  "metadata": {}
}

Cancel Pix charge

POST/api/payments/{paymentId}/cancel

Cancels one PENDING Pix Automático charge, until the day before its billingDate; after that, or for any other payment, Outpost returns 409 invalid_status. The payment becomes CANCELED, Outpost sends payment.canceled, and the authorisation stays ACTIVE. On a VARIABLE authorisation, to change the amount, cancel the charge, then create a new one for the same billingDate while it is at least 2 days away. The request has no body.

Request Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Idempotency-KeystringYesUnique key for this request. See Conventions

Path Parameters

ParameterTypeRequiredDescription
paymentIdstringYesOutpost payment ID (UUID)

Response 200 OK

{
  "id": "01a211fa-92e0-7952-800d-54bf6e80d923",
  "merchantReference": "sub-1042-2026-12",
  "status": "CANCELED",
  "amount": { "amount": "49.90", "currency": "BRL" },
  "paymentMethod": {
    "type": "pixAutomatico",
    "pixAuthorisationId": "01a19c91-4eb8-7231-b916-d081927e245a",
    "billingDate": "2026-12-02"
  },
  "createdAt": "2026-11-25T09:12:44Z",
  "canceledAt": "2026-11-28T16:40:02Z",
  "metadata": {}
}

Get Pix authorisation

GET/api/pix-authorisations/{pixAuthorisationId}

Returns the authorisation's current state and terms.

Path Parameters

ParameterTypeRequiredDescription
pixAuthorisationIdstringYesOutpost Pix Automático authorisation ID (UUID)

Response 200 OK

{
  "id": "01a19c91-4eb8-7231-b916-d081927e245a",
  "status": "ACTIVE",
  "merchantCustomerReference": "CUST-7781",
  "amountType": "FIXED",
  "recurringAmount": "49.90",
  "minAmount": null,
  "currency": "BRL",
  "frequency": "MONTHLY",
  "startsAt": "2026-11-02",
  "endsAt": null,
  "retryPolicy": true,
  "enrolmentPaymentId": "01a19c91-4eb8-7414-9330-f468f638178e",
  "createdAt": "2026-11-02T14:02:11Z",
  "approvedAt": "2026-11-02T14:05:40Z",
  "canceledAt": null,
  "canceledBy": null
}

Response Fields

ParameterTypeRequiredDescription
idstring-Pix authorisation ID (UUID)
statusstring-See the status table below
merchantCustomerReferencestring-As sent on the enrolment
amountType, recurringAmount, minAmountstring-As sent on the enrolment. The amount field not used by amountType is null
currencystring-Always BRL
frequency, endsAt, retryPolicy--As sent; endsAt is null when omitted
startsAtstring-The approval date, YYYY-MM-DD. Null until the shopper approves
enrolmentPaymentIdstring-The payment that created the authorisation
createdAt, approvedAt, canceledAtstring-ISO 8601 timestamps. approvedAt and canceledAt are null until that happens
canceledBystring-MERCHANT or SHOPPER once CANCELED, otherwise null
StatusMeaning
PENDING_APPROVALThe shopper has not yet approved the authorisation in their bank app
ACTIVEApproved. Outpost accepts pixAutomatico charges against it
CANCELEDEnded by you or by the shopper. Final
EXPIREDReached endsAt, or the shopper did not approve in time. Final
REJECTEDRefused by the shopper or the shopper's bank. Final

Cancel Pix authorisation

POST/api/pix-authorisations/{pixAuthorisationId}/cancel

Ends an ACTIVE or PENDING_APPROVAL authorisation immediately and sends pix_authorisation.canceled. Cancelling a PENDING_APPROVAL authorisation fails its enrolment payment with authorisation_canceled, as does any PENDING charge not yet on the day of its billingDate; a charge due that day still runs. Cancelling an authorisation in any other status returns 409 invalid_status. The shopper can also cancel in their bank app, with the same effects. A cancelled authorisation cannot be reactivated: enrol again. The request has no body.

Request Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Idempotency-KeystringYesUnique key for this request. See Conventions

Path Parameters

ParameterTypeRequiredDescription
pixAuthorisationIdstringYesOutpost Pix Automático authorisation ID (UUID)

Response 200 OK

The authorisation, as Get Pix authorisation returns it, with status CANCELED and canceledAt and canceledBy set.

Create refund

POST/api/payments/{paymentId}/refunds

Refunds a captured payment in full or in part. Outpost issues the corresponding tax document. The refund starts as INITIATED; the result arrives as a refund.completed or refund.failed webhook. A refund doesn't change the payment: it stays CAPTURED. A payment can have several partial refunds; their total can't exceed the captured amount, or Outpost returns 400 invalid_state on amount.

Request Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringYesUnique key for this request. See Conventions

Path Parameters

ParameterTypeRequiredDescription
paymentIdstringYesPayment to refund (UUID)

Request Body Parameters

ParameterTypeRequiredDescription
merchantReferencestringYesYour refund reference
amountobjectNoamount (decimal string) + currency. Omit to refund the remaining amount in full
reasonstringNoREQUESTED_BY_CUSTOMER, DUPLICATE, FRAUDULENT or OTHER. Returned on the refund; null when omitted

Response 201 Created

{
  "id": "01a18708-cb98-7f0f-8672-bf02c2e98dc0",
  "paymentId": "01a182d1-82b8-7b18-bf89-08ff16b3fbfd",
  "merchantReference": "refund-1042-1",
  "status": "INITIATED",
  "amount": { "amount": "120.99", "currency": "EUR" },
  "reason": "REQUESTED_BY_CUSTOMER",
  "createdAt": "2026-10-29T09:41:03Z"
}
Refund statusMeaning
INITIATEDOutpost accepted the refund
COMPLETEDThe payment provider confirmed the refund. Final
FAILEDThe payment provider could not complete the refund. Final; create a new refund to try again

Code Example

curl -X POST \
  "https://api.outpostanywhere.com/api/payments/$PAYMENT_ID/refunds" \
  -H "Authorization: Bearer $OUTPOST_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "merchantReference": "refund-1042-1",
    "amount": { "amount": "120.99", "currency": "EUR" },
    "reason": "REQUESTED_BY_CUSTOMER"
  }' | jq

Webhooks

Register an endpoint for each merchant with POST /api/webhooks, using that merchant's access token, and subscribe to the events below. The signing secret is returned once on creation.

EventSent whenSubscribe
payment.capturedThe payment was authorised and capturedRequired
payment.failedThe payment was declined, failed, or expired before the shopper completed it. data includes the failure objectRequired
payment.canceledYou cancelled a PENDING Pix Automático charge. data is as for payment.failed, with canceledAt instead of failedAt and failurePix Automático only
pix_authorisation.approvedThe shopper approved a Pix Automático authorisation. Example belowPix Automático only
pix_authorisation.rejectedThe shopper or the shopper's bank refused a Pix Automático authorisationPix Automático only
pix_authorisation.canceledA Pix Automático authorisation was cancelled. data.canceledBy is MERCHANT (through this API) or SHOPPER (in their bank app)Pix Automático only
pix_authorisation.expiredA Pix Automático authorisation reached endsAt, or the shopper did not approve it in timePix Automático only
refund.completedThe payment provider confirmed the refundRequired
refund.failedThe refund could not be completedRequired

The required events are the ones a one-time payment and refund integration needs. In each event's data, paymentId, refundId and pixAuthorisationId are the id of the payment, refund or Pix authorisation. Events carry the key facts of what happened; fetch the payment with GET /api/payments/{paymentId} for anything else, such as networkTransactionId. Events don't name the merchant, so register a separate URL for each merchant to know which signing secret to verify with. Treat event IDs as opaque, and ignore data fields you don't use. payment.captured fires for every captured payment of the merchant, including ones it took outside this API: match on paymentId.

payment.captured

{
  "id": "evt_payment_captured_01a182d1-8a88-7ac9-96a6-ca7202384964",
  "type": "payment.captured",
  "created": "2026-10-28T14:02:13Z",
  "data": {
    "paymentId": "01a182d1-82b8-7b18-bf89-08ff16b3fbfd",
    "merchantReference": "order-1042",
    "amount": { "amount": "120.99", "currency": "EUR" },
    "capturedAt": "2026-10-28T14:02:12Z",
    "metadata": {}
  }
}

payment.failed

data.failure has the same fields as on the payment. See Payment failures.

{
  "id": "evt_payment_failed_01a1830f-b0b0-7a9b-a354-2ace229bfacf",
  "type": "payment.failed",
  "created": "2026-10-28T15:10:06Z",
  "data": {
    "paymentId": "01a1830f-a8e0-7448-bd72-c4d4d3dd8e1b",
    "merchantReference": "order-1043",
    "amount": { "amount": "120.99", "currency": "EUR" },
    "failure": {
      "code": "card_declined",
      "message": "The card was declined by the issuer.",
      "declineCode": "05",
      "retryable": false
    },
    "failedAt": "2026-10-28T15:10:05Z",
    "metadata": {}
  }
}

refund.completed

{
  "id": "evt_refund_completed_01a1870a-e2c0-7752-8b1f-8515a0199bd6",
  "type": "refund.completed",
  "created": "2026-10-29T09:43:20Z",
  "data": {
    "refundId": "01a18708-cb98-7f0f-8672-bf02c2e98dc0",
    "paymentId": "01a182d1-82b8-7b18-bf89-08ff16b3fbfd",
    "merchantReference": "refund-1042-1",
    "amount": { "amount": "120.99", "currency": "EUR" },
    "reason": "REQUESTED_BY_CUSTOMER",
    "completedAt": "2026-10-29T09:43:19Z"
  }
}

refund.failed

A refund's failure has a message only, with no code.

{
  "id": "evt_refund_failed_01a1870a-e2c0-7e74-b454-db21ceca6dc7",
  "type": "refund.failed",
  "created": "2026-10-29T09:43:20Z",
  "data": {
    "refundId": "01a18708-cb98-7f0f-8672-bf02c2e98dc0",
    "paymentId": "01a182d1-82b8-7b18-bf89-08ff16b3fbfd",
    "merchantReference": "refund-1042-1",
    "amount": { "amount": "120.99", "currency": "EUR" },
    "reason": "REQUESTED_BY_CUSTOMER",
    "failure": {
      "message": "The payment provider declined the refund."
    },
    "failedAt": "2026-10-29T09:43:19Z"
  }
}

pix_authorisation.approved

pix_authorisation.rejected, .canceled and .expired carry the same data with that status; canceled also sets canceledAt and canceledBy (MERCHANT or SHOPPER).

{
  "id": "evt_pix_authorisation_approved_01a19c94-8308-7465-99fd-bbefd4aea268",
  "type": "pix_authorisation.approved",
  "created": "2026-11-02T14:05:41Z",
  "data": {
    "pixAuthorisationId": "01a19c91-4eb8-7231-b916-d081927e245a",
    "status": "ACTIVE",
    "merchantCustomerReference": "CUST-7781",
    "enrolmentPaymentId": "01a19c91-4eb8-7414-9330-f468f638178e",
    "startsAt": "2026-11-02",
    "frequency": "MONTHLY",
    "approvedAt": "2026-11-02T14:05:40Z",
    "canceledAt": null,
    "canceledBy": null
  }
}

Delivery and retries

  • Acknowledge a delivery with any 2xx status. Each attempt has 30 seconds to respond.
  • A 429 or 5xx response is retried. Any other 4xx response is a permanent failure and stops delivery of that event.
  • Retries use exponential backoff: at most 8 attempts, capped at 9 hours in total.
  • Event ids are the same on every retry of the same event. Deduplicate on the full id.

Verifying signatures

Each request carries an Outpost-Signature header of the form t=<timestamp>,v1=<hmac>. t is a Unix timestamp in seconds; v1 is the hex-encoded HMAC-SHA256 of {t}.{raw body}, keyed with your signing secret (whsec_…) exactly as returned. Compare in constant time, and reject a request whose t is more than 5 minutes old. Always verify the signature before acting on a payload.

Payment failures

A FAILED payment carries a failure object, on the payment and in the payment.failed webhook.

FieldDescription
failure.codeWhy the payment failed, from the list below
failure.messageHuman-readable explanation. Not for display to the shopper
failure.declineCodeRaw issuer or provider code, for information only. Its format varies by provider. Omitted when the provider returns none
failure.retryableAlways false on Pix Automático charges: Outpost runs any retries itself under retryPolicy. Otherwise, true when a new payment with the same card may succeed: always for processing_error, and for card_declined or insufficient_funds when the issuer marks the decline as temporary. false otherwise
failure.codeMeaning
card_declinedThe issuer declined the card without a more specific reason
insufficient_fundsThe card or account has insufficient funds or credit
expired_cardThe card has expired
incorrect_cvcThe CVC is incorrect
authentication_failedThe shopper failed or abandoned 3-D Secure, did not complete the bank redirect or Pix payment in time, or did not approve a Pix Automático enrolment before it expired
authentication_requiredThe issuer refused a merchant-initiated charge without the shopper authenticating. Ask the shopper to pay again with recurring.initiator CUSTOMER
authorisation_rejectedThe shopper or the shopper's bank refused a Pix Automático enrolment
authorisation_canceledThe Pix Automático authorisation was cancelled before the day of the charge's billingDate, or before the shopper approved the enrolment
debit_canceledThe shopper cancelled this debit in their bank app after the pre-debit notice. The Pix Automático authorisation stays ACTIVE
authorisation_amount_exceededThe charge is above the ceiling the shopper set in their bank app for a VARIABLE Pix Automático authorisation
fraud_suspectedThe issuer or Outpost blocked the payment as suspected fraud
processing_errorA provider or network error prevented processing

Payment status

StatusMeaning
PENDINGOutpost has accepted the payment and is waiting for the bank. The result arrives by webhook on or after paymentMethod.billingDate, unless the charge or its authorisation is cancelled first. Pix Automático charges only
REQUIRES_ACTIONWaiting for the shopper: 3-D Secure, bank redirect or Pix QR code
CAPTUREDAuthorised and captured. Final. A zero-amount card verification also ends CAPTURED, with nothing charged
CANCELEDYou cancelled a PENDING Pix Automático charge. Final
FAILEDDeclined, failed or expired. Final; create a new payment to retry. For a Pix Automático charge, create the next cycle's payment instead

Error handling

All error responses follow a consistent structure with a category code and, for invalid requests, the fields at fault. A declined payment is not an error: it returns 201 with status FAILED.

HTTPCodeDescription
400invalid_argumentThe request is invalid. See errors for the fields
400invalid_idempotency_keyThe Idempotency-Key header is blank or longer than 255 characters
400invalid_stateThe refund amount exceeds what remains refundable on the payment. errors names amount
401-Missing or invalid access token
404not_foundPayment or Pix authorisation not found for this merchant
409invalid_statusThe payment or authorisation is not in a status that allows the operation, for example refunding a failed payment, charging a cancelled Pix Automático authorisation, or a second charge for the same billing cycle
422idempotency_key_reusedThe Idempotency-Key was already used for a different request body, so Outpost created nothing
429rate_limitedToo many requests. Retry after the Retry-After header
{
  "code": "invalid_argument",
  "errors": [{ "field": "customer.billingAddress.country", "message": "is required" }]
}