API Documentation

Base URL: https://jopay.me/api/checkout/v1

Authentication

Include your API key in the Authorization header as a Bearer token.

Find your API keys in Admin → Settings → Checkout API Keys. Use test keys for development and live keys for production.

Header
Authorization: Bearer sk_live_your_api_key
POST

/sessions

Create Checkout Session

Create a new checkout session and redirect your customer to the returned URL. After payment, they'll be redirected to your success_url.

Parameters

line_items required array

Products to purchase. Each item: name, amount (cents), currency, quantity

success_url required string

Redirect URL after payment. We append ?session_id={id}

cancel_url required string

Redirect URL if customer cancels

customer_email string

Email for invoice delivery

metadata object

Key-value pairs returned in webhooks

curl -X POST https://jopay.me/api/checkout/v1/sessions \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "line_items": [{
      "name": "Premium Coffee Beans",
      "amount": 2500,
      "currency": "eur",
      "quantity": 1
    }],
    "customer_email": "customer@example.com",
    "success_url": "https://yoursite.com/success",
    "cancel_url": "https://yoursite.com/cancel",
    "metadata": {"order_id": "12345"}
  }'

Response

{
  "id": "cs_a1b2c3d4e5f6...",
  "checkout_url": "https://jopay.me/checkout/cs_a1b2c3d4e5f6",
  "status": "pending",
  "amount_cents": 2500,
  "currency": "eur",
  "expires_at": "2025-01-10T13:00:00Z"
}

Webhooks

Configure your webhook endpoint in Admin → Settings → Checkout Webhook. We send events when payment status changes.

Events

checkout.session.completed

Payment successful. Fulfill the order.

checkout.session.expired

Session expired without payment.

checkout.payment.failed

Payment attempt failed.

Webhook Payload

{
  "event": "checkout.session.completed",
  "data": {
    "id": "cs_a1b2c3d4e5f6...",
    "status": "completed",
    "amount_cents": 2500,
    "currency": "eur",
    "customer_email": "customer@example.com",
    "metadata": {"order_id": "12345"},
    "completed_at": "2025-01-10T12:05:00Z"
  },
  "created_at": "2025-01-10T12:05:01Z"
}

Verifying Signatures

Verify the X-JoPay-Signature header to ensure webhooks are authentic.

const crypto = require('crypto');

// Header format: t=timestamp,v1=signature
function verifySignature(payload, signatureHeader, secret) {
  const [timestamp, hash] = signatureHeader
    .split(',')
    .map(p => p.split('=')[1]);

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${payload}`)
    .digest('hex');

  return hash === expected;
}

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-jopay-signature'];
  if (!verifySignature(JSON.stringify(req.body), signature, SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  // Handle the event
});

Need Help?

Contact us if you have questions about the API.