ChargX Documentation

Double-Redirect Flow

This recipe shows how to implement a Double-Redirect checkout flow.

Overview

The double-redirect flow has five steps:

  1. Merchant checkout — User clicks Pay button your site which saves the order as Pending and redirects to the Chargx Payment Form site
  2. External purchase — User pays on the Chargx Payment Form site with their card.
  3. Automatic redirect back — The Chargx Payment Form redirects the user to your Success URL (provided in the API call) after payment.
  4. Auto-redemption — Your site receives a transaction completion via the Webhook, then calls the Chargx API server-to-server to verify and claim the value.
  5. Order completion — Your site updates the order to Paid and shows the receipt.

Steps

1. Merchant checkout — save order and create ChargX Payment Widget

When the user clicks Pay, then:

  • your site creates a pending order in your system
  • then creates a ChargX Payment Widget via the API and redirect the user to its checkout URL. Include your order ID in the success_url so you can reconcile when they return.

Example:

// User clicked "Pay with Credit Card" for $50
const orderId = 345; // your internal order ID
await yourBackend.createOrder({ orderId, amount: 50, status: "pending" });

const successUrl = `https://yoursite.com/checkout/success?orderId=${orderId}`;

const response = await fetch("https://api.chargx.io/v1/payment-request", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-publishable-api-key": "pk_your_publishable_key",
  },
  body: JSON.stringify({
    amount: 50,
    currency: "usd",
    success_url: successUrl,
    type: "card", // bank-to-bank
  }),
});

const data = await response.json();
if (!response.ok) throw new Error(data?.message ?? data?.error ?? "Failed to create payment widget");

const checkoutUrl = data.payment_request.checkout_url;
window.location.href = checkoutUrl;

2. External purchase

The user is on the ChargX Payment Form. They use their credit card to make a payment.

3. Automatic redirect back

After the payment is confirmed, the ChargX Payment Form redirects the user to the Success URL you provided in step 1. We also append a chargx_order_id in the URL (query parameter) to identify the order.

Example URL your user might land on:

https://yoursite.com/checkout/success?orderId=345&chargx_order_id=ord_abc123&code=GC-XXXX-YYYY

4. Auto-redemption

Webhook setup

This section requires to have Webhook endpoint setup in your site backend.

  1. Go to the Chargx Dashboard and navigate to the "Settings -> Webhooks" section.
  2. Click on the "Create webhook" button.
  3. Enter the name, webhook URL and select the events you want to receive.
  4. Click on the "Create" button.

See Webhooks Setup for more details.

Your site (backend) receives the Webhook request from Chargx - server-to-server Once receive, then your site (backend) should:

  1. Verify the code/order_id is valid
  2. Claim the value

Do not rely only on the URL parameters for security — always verify and claim via the provider’s API on the backend.

Example (server-side):

Read these three values from the webhook payload (data.object):

  • external_order_id — Your internal order ID (the one you passed when creating the payment).
  • order_id — ChargX order ID.
  • order_display_id — ChargX order display ID.

JavaScript (Node):

// your site backend webhook endpoint
app.post("/webhook", async (req, res) => {
  const payload = req.body;
  const order_id = parseInt(payload?.data?.object?.external_order_id ?? 0, 10);
  const chargx_order_id = payload?.data?.object?.order_id ?? null;
  const chargx_order_display_id = payload?.data?.object?.order_display_id ?? null;

  if (!order_id) {
    return res.status(400).json({ error: "Missing external_order_id" });
  }

  // Server-to-server: verify and claim (e.g. using chargx_order_id with ChargX API)
  const claimResult = await yourBackend.verifyAndClaimFromThirdParty({
    order_id,
    chargx_order_id,
    chargx_order_display_id,
  });

  if (!claimResult.success) {
    throw new Error("Failed to claim the value");
  }

  // Update order to Paid in your system
  await yourBackend.updateOrderStatus(order_id, "paid");
});

async function verifyAndClaimFromThirdParty({ order_id, chargx_order_id, chargx_order_display_id }) {
  // 1) Verify with ChargX API (e.g. get order by order_id)
  const verifyRes = await fetch(`https://api.chargx.io/v1/orders/${chargx_order_id}`, {
    headers: {
      "Authorization": "Bearer " + process.env.CHARGX_SECRET_KEY,
    },
  });
  const orderData = await verifyRes.json();
  if (!verifyRes.ok || !orderData?.order) {
    return { success: false };
  }

  // 2) Optionally confirm / claim — then update your system
  // Use order_id (your external_order_id) to mark the order as paid
  return { success: true };
}

5. Order completion

Your user is on a Success URL page. The page should show a loader with a text Finalizing your order and updating inventory... and ping your backend for order status. Once status is Paid, then your site should finally navigates a user to the order confirmation page.

Implementation references

The double-redirect flow is implemented by the Chargx Woocommerce plugin (enabled via payment_redirection_flow config). Use it as a reference to implement the double-redirect flow in your site backend. The plugin also automatically registers a webhook endpoint using Admin API to receive the webhook requests from ChargX.

Payment Form: passing billing information

The Payment Form accepts billing information as query parameters, e.g.

• email
• phone-number
• street-address
• unit-address
• state
• zip-code
• country
• external_order_id
https://dashboard.chargx.io/payment-form/01KN4JV2DC2V35F2121Z0ZQG9A?success_url=https%3A%2F%2Fwp-test.mysite.com%2F%3Fwc-api%3Dwc_gateway_chargx_card_success_url%26order_id%3D125&email=olena.test%40gmail.com&phone-number=+118731944911&street-address=Molodizhna&unit-address=11&city=NewYork&state=NY&zip-code=11111&country=US&external_order_id=125

In this case the Payment Form will be rendered with the billing information fields prefilled.

Security notes

  • Always verify and claim server-side. Do not trust the redirect URL alone; the third-party API is the source of truth.
  • Idempotency: Use the order ID (or a idempotency key) so that duplicate redirects do not result in double redemption.
  • Success URL: Use HTTPS and a URL that only your backend can interpret; avoid exposing sensitive tokens in the client path if possible.