← Back to API Docs

Checkout

Accept a payment with Checkout

Create a Checkout Session on your server, open Hosted Checkout, then mark the order paid after confirmation (ship or unlock access).

Accept a payment with Checkout

Use Checkout when a buyer pays a fixed amount once (order, invoice, top-up). Your server creates a Checkout Session; the buyer pays on Hosted Checkout (pay.doggiepay.com) or via the Button SDK; after webhook checkout.paid (and/or a trusted server-side status read), mark the order paid and continue shipping or unlocking access.

Prerequisite: Getting started (Secret key + Request-Id).

Your server                Doggie Pay                 Buyer
    |                           |                       |
    |-- POST /checkout/sessions -->|                       |
    |<-- hosted_url, id -----------|                       |
    |-- open hosted_url ---------->|---------------------->|
    |                           |<-- on-chain USDC/USDT --|
    |<-- webhook checkout.paid ----|                       |
    |-- fulfill order -------------|                       |

1. Create a Checkout Session

POST /v1/checkout/sessions
Auth: Secret or Publishable (+ Request-Id)

Request body

FieldTypeRequiredDescription
amountstringYesPositive decimal amount as a string (e.g. "19.99")
currencystringYesAsset code, e.g. USDC, USDT
chainstringCond.Single chain alias (e.g. ETH, BASE). Use chain or chains.
chainsstring[]Cond.Multiple chain aliases; buyer can pick among pre-claimed addresses
success_urlstringNoRedirect after Hosted success flow
cancel_urlstringNoRedirect after cancel
metadataobjectNoString map for your correlation IDs (order_id, etc.)

Example

curl -sS https://api.doggiepay.com/v1/checkout/sessions \
  -H "Authorization: Bearer dp_live_sk_YOUR_SECRET" \
  -H "X-DoggiePay-Request-Id: $(uuidgen | tr '[:upper:]' '[:lower:]')" \
  -H "Idempotency-Key: order-1001-pay" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "19.99",
    "currency": "USDC",
    "chain": "BASE",
    "success_url": "https://merchant.example/orders/1001/paid",
    "cancel_url": "https://merchant.example/orders/1001/cancel",
    "metadata": { "order_id": "1001" }
  }'

Response data fields

FieldTypeDescription
iduuidSession id (same as payment_id)
payment_iduuidPayment aggregate id (alias of id)
statusstringpending | paid | expired | cancelled | partial_refund | refunded
amountstringCharged amount
currencystringAsset
chainstringPrimary / selected chain alias
addressstringDeposit address when a single chain is used
chain_optionsarrayMulti-chain: [{ "chain", "address" }, …]
client_secretstringFor Hosted / public poll (treat as sensitive)
hosted_urlstringOpen this URL for the buyer (…/c/{id}#client_secret=…)
expires_atstringISO-8601 expiry when present
success_url / cancel_urlstringEcho of create input
metadataobjectEcho of create input
refundableboolWhether a refund can be requested
cancellableboolWhether cancel is allowed
tx_hashstringSet after on-chain confirmation (when available)
refunded_amountstringCumulative refunded amount when applicable
created_atstringISO-8601

Recommended: create with Secret on the server, then pass only hosted_url (or id + client_secret) to the browser.

Create errors

HTTPerror.codeMeaning
400invalid_amountBad amount/currency
400invalid_chainChain not enabled / invalid
400invalid_bodyNon-JSON body
503pool_exhaustedNo idle payment address (retry later)
503checkout_unavailableCheckout not configured
422checkout_create_failedOther create failure

2. Open Hosted Checkout

Redirect or window.open the hosted_url. Hosted lives on https://pay.doggiepay.com.

Button SDK (optional)

npm install @doggiepay/checkout
import { mountDoggiePayButton } from "@doggiepay/checkout";

mountDoggiePayButton("#pay", {
  hostedUrl,              // from your server create response
  openMode: "new_tab",    // or "same_tab"
  onPaid: () => refreshOrder(),
});
OptionTypeDescription
hostedUrlstringPreferred: full URL from create
sessionId + clientSecretstringAlternative to hostedUrl
openModestringnew_tab (default) or same_tab
onPaidfunctionFired when client-side poll sees paid (still verify with webhook)

3. Read session status

Merchant (Secret)

GET /v1/checkout/sessions/{id}

curl -sS "https://api.doggiepay.com/v1/checkout/sessions/SESSION_UUID" \
  -H "Authorization: Bearer dp_live_sk_YOUR_SECRET" \
  -H "X-DoggiePay-Request-Id: $(uuidgen | tr '[:upper:]' '[:lower:]')"

Public / Hosted poll (no Bearer)

Provide client_secret via query or header:

GET /v1/checkout/sessions/{id}?client_secret=…
X-DoggiePay-Client-Secret: …

Do not mark the order paid from a browser redirect alone — use Webhooks.

4. Cancel a session

POST /v1/checkout/sessions/{id}/cancel
Auth: Secret, or client_secret (Hosted cancel)

Only while cancellable is true (typically pending).

Emits webhook checkout.cancelled.

5. After payment is confirmed

  1. Prefer checkout.paid webhook as source of truth
  2. Optionally double-check GET …/sessions/{id} → status === "paid"
  3. Idempotently mark your order paid using payment_id / metadata.order_id, then ship or unlock access
  4. Handle checkout.expired and checkout.cancelled so inventory is released

6. Refund a paid Checkout (optional)

POST /v1/refunds — Secret; Payment-only (not customer deposits).

FieldRequiredDescription
payment_idYes*Session / payment UUID (checkout_session_id accepted as alias)
checkout_session_idYes*Alias of payment_id
amountYesRefund amount string
currencyYesMust match payment
to_addressYesBuyer receive address
chainYesOutflow chain (enabled for the asset)
curl -sS https://api.doggiepay.com/v1/refunds \
  -H "Authorization: Bearer dp_live_sk_YOUR_SECRET" \
  -H "X-DoggiePay-Request-Id: $(uuidgen | tr '[:upper:]' '[:lower:]')" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_id": "SESSION_UUID",
    "amount": "19.99",
    "currency": "USDC",
    "chain": "BASE",
    "to_address": "0xBuyer…"
  }'

Follow progress via refund.* webhooks and GET /v1/refunds.

7. Next steps

  • Webhooks — HMAC verify checkout.paid
  • Customers rail — long-lived deposit addresses for in-app balances