Skip to main content
POST
/
checkout
/
create
Create checkout session
curl --request POST \
  --url https://api.wallet.example/opencharge/checkout/create \
  --header 'Content-Type: application/json' \
  --header 'X-OC-ID: <x-oc-id>' \
  --header 'X-OC-Nonce: <x-oc-nonce>' \
  --header 'X-OC-Signature: <x-oc-signature>' \
  --header 'X-OC-Timestamp: <x-oc-timestamp>' \
  --data '
{
  "order": {
    "id": "ord_abc123",
    "ocid": 500,
    "reference": "INV-001",
    "amount": "99.99",
    "currency": "USD",
    "items": [
      {
        "id": "item_001",
        "name": "Product A",
        "quantity": 1,
        "price": "99.99"
      }
    ],
    "memo": "Order from Merchant Store",
    "createdAt": 1706313600,
    "expiresAt": 1706400000,
    "accepts": [
      100,
      101,
      102
    ]
  },
  "signature": "a1b2c3d4e5f6...merchant_sig",
  "merchantOcid": 500,
  "urls": {
    "success": "https://merchant.example/checkout/success",
    "cancel": "https://merchant.example/checkout/cancel"
  }
}
'
{
  "checkout_url": "https://checkout.wallet.example/pay/sess_xyz789",
  "session_id": "sess_xyz789",
  "expires_at": 1706400000
}

Overview

Merchant Gateways call this endpoint to create a hosted checkout session. You return a URL where the end user will be redirected to complete payment on your checkout page.

When This Is Called

  1. A customer initiates checkout at a merchant’s website
  2. The merchant sends the order to their Merchant Gateway
  3. The Merchant Gateway forwards the order to your Payment Gateway
  4. You create a checkout session and return the URL
  5. The customer is redirected to your checkout page

Implementation

app.post('/checkout/create', signatureAuth, async (req, res) => {
  const { order, signature, merchantOcid, urls } = req.body;
  const merchantGatewayOcid = req.headers['x-oc-id'];

  // 1. Verify the order signature matches the merchant
  const merchant = await fetchMerchantMetadata(merchantOcid);
  if (!verifyOrderSignature(order, signature, merchant.config.publicKey)) {
    return res.status(400).json({
      error: { code: 'INVALID_SIGNATURE', message: 'Order signature invalid' }
    });
  }

  // 2. Create checkout session
  const session = await db.createCheckoutSession({
    id: crypto.randomUUID(),
    merchantOcid,
    merchantGatewayOcid,
    order,
    signature,
    urls,
    status: 'pending',
    expiresAt: Date.now() + 30 * 60 * 1000
  });

  // 3. Return checkout URL
  res.json({
    checkout_url: `https://checkout.yourgateway.com/${session.id}`,
    expires_at: Math.floor(session.expiresAt / 1000)
  });
});

After Payment

When the user completes payment on your checkout page:
  1. Credit the merchant gateway account.
  2. Redirect the user to the urls.success URL
async function completeCheckout(session, user) {
  // Generate transfer proof for the merchant gateway
  const proof = await generateProof(user, session.order, session.merchantOcid);

  // Update session
  await db.updateCheckoutSession(session.id, {
    status: 'completed',
    proof
  });

  // Redirect user to success URL
  return session.urls?.success || '/success';
}

Settlement Guide

Learn about the different ways to settle payments with merchants

Headers

X-OC-ID
string
required

Caller's OCID

X-OC-Timestamp
string
required

Unix timestamp in seconds

X-OC-Nonce
string
required

Unique request identifier

X-OC-Signature
string
required

secp256k1 ECDSA signature

Body

application/json
order
object
required
signature
string
required

Merchant's signature on the order

merchantOcid
integer
required

The merchant's OCID

urls
object
required

Response

Checkout session created

checkout_url
string<uri>
required

URL to redirect user to for payment

session_id
string
required

Unique checkout session identifier

expires_at
integer

Unix timestamp when session expires