> ## Documentation Index
> Fetch the complete documentation index at: https://docs.launcx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Redirect After Payment

> Send your customer back to your site after a payment link succeeds or fails.

When you [create a payment](/payments#create-payment), the response contains a `checkoutUrl` — a hosted payment page where your customer completes the payment. By default, after the payment finishes the customer stays on that page.

To bring the customer back to your site, append redirect parameters to the `checkoutUrl` **before** you send the customer to it. The hosted page reads them and redirects the customer to your success URL when the payment reaches `SUCCESS`, or to your failure URL when it becomes `FAILED` or `EXPIRED`.

## Redirect parameters

| Parameter | Type   | Required | Notes                                                                                                                                                                                           |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `rs`      | string | No       | **R**edirect on **s**uccess. Base64-encoded absolute URL the customer is sent to when the payment succeeds.                                                                                     |
| `rf`      | string | No       | **R**edirect on **f**ailure. Base64-encoded absolute URL the customer is sent to when the payment fails **or expires**.                                                                         |
| `ar`      | string | No       | **A**uto-**r**edirect. Set to `true` (case-insensitive) to redirect automatically after a 10-second countdown. Any other value (or omitting it) shows a button the customer clicks to continue. |

All three parameters are optional and independent — you can set only `rs`, only `rf`, or both. If a parameter is missing, the customer simply stays on the result screen for that outcome.

<Note>
  The redirect URLs must be **base64-encoded** (standard or URL-safe base64 both work; padding is optional) and must decode to an absolute `http://` or `https://` URL. A value that fails to decode, or decodes to anything other than an http(s) URL, is ignored and no redirect is offered.
</Note>

<Warning>
  The customer is redirected to your URL **exactly as you provided it** — no query parameters are appended by the payment page. Include everything you need to identify the payment (for example your `orderId`) in the URL before encoding it. Never treat the redirect itself as proof of payment; always confirm the final status via webhook or the payment status API.
</Warning>

## How it looks to the customer

* **`ar=true`** — after the payment resolves, the result screen shows a 10-second countdown ring with a "redirect now" button. When the countdown reaches zero (or the customer clicks the button), the browser navigates to your URL.
* **`ar` omitted** — the result screen shows a button; the customer is redirected only when they click it.

## End-to-end example

The snippet below runs **on your backend** — the API key must never reach the browser. It creates the payment, takes `checkoutUrl` from the response, and attaches the redirect parameters.

```typescript theme={null}
// Encode a redirect URL as URL-safe base64 (Node.js 16+).
// In other runtimes, any base64 encoder works — the payment page
// accepts standard and URL-safe base64, with or without padding.
function encodeRedirectUrl(url: string): string {
  return Buffer.from(url, "utf8").toString("base64url");
}

interface CreatePaymentResponse {
  success: boolean;
  data: {
    orderId: string;
    checkoutUrl: string;
    qrPayload: string;
    playerId: string;
    totalAmount: number;
    // Normally PENDING. A payment that already completed (for example
    // a duplicate create request) returns its final status instead,
    // and the response carries no qrPayload.
    status: "PENDING" | "SUCCESS" | "EXPIRED" | "FAILED";
  };
}

async function createCheckoutUrl(): Promise<string> {
  // 1. Create the payment.
  const response = await fetch("https://live.launcx.com/api/v1/payments", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": process.env.LAUNCX_API_KEY!,
      "x-timestamp": Date.now().toString(),
    },
    body: JSON.stringify({
      price: 15000,
      playerId: "payer_id",
    }),
  });

  if (!response.ok) {
    throw new Error(`Create payment failed: ${response.status}`);
  }

  const payment: CreatePaymentResponse = await response.json();
  const { orderId, checkoutUrl } = payment.data;

  // 2. Build the redirect URLs. Embed your own order reference —
  //    the payment page redirects to these URLs verbatim.
  const successUrl = `https://merchant.example.com/checkout/success?orderId=${orderId}`;
  const failureUrl = `https://merchant.example.com/checkout/failed?orderId=${orderId}`;

  // 3. Attach the redirect parameters to the checkout URL.
  const checkout = new URL(checkoutUrl);
  checkout.searchParams.set("rs", encodeRedirectUrl(successUrl));
  checkout.searchParams.set("rf", encodeRedirectUrl(failureUrl));
  checkout.searchParams.set("ar", "true"); // auto-redirect after 10s

  return checkout.toString();
}
```

Hand the finished URL to the browser — respond with a `302` to it, or return it from your route and navigate client-side:

```typescript theme={null}
// In the browser:
const { checkoutUrl } = await fetch("/api/checkout", { method: "POST" }).then((r) => r.json());
window.location.assign(checkoutUrl);
```

A finished checkout URL looks like this:

```text theme={null}
https://live.launcx.com/external/payments/b36e39bc-c5fb-4c32-ab46-7260e14d1881/receive?rs=aHR0cHM6Ly9tZXJjaGFudC5leGFtcGxlLmNvbS9jaGVja291dC9zdWNjZXNzP29yZGVySWQ9YjM2ZTM5YmMtYzVmYi00YzMyLWFiNDYtNzI2MGUxNGQxODgx&rf=aHR0cHM6Ly9tZXJjaGFudC5leGFtcGxlLmNvbS9jaGVja291dC9mYWlsZWQ_b3JkZXJJZD1iMzZlMzliYy1jNWZiLTRjMzItYWI0Ni03MjYwZTE0ZDE4ODE&ar=true
```

## Handling the customer's return

When the customer lands back on your site:

1. Read your order reference from the URL you constructed (e.g. `orderId`).
2. Look up the payment's final status on your backend — via the [webhook notification](/webhooks) you received, or by querying the [payment status API](/payments#get-payment).
3. Render your own success or failure page based on that verified status.

<Warning>
  Redirect URLs are visible to the customer and can be opened directly, so your success page must not fulfill an order on its own. Fulfillment should only ever be driven by the verified payment status.
</Warning>
