Skip to content

Search documentation

Try “webhook signature” or “amountUsd”. Use Tab or arrow keys to explore results.

    Open app
    Open app

    Documentation navigation

    Your first test payment

    Create a hosted checkout, pay with test tokens, and verify the result on your server.

    On this page

    1. Prepare a merchant profile

    • Sign in, choose business payments or integration, and complete your profile’s billing details.
    • Create a store. Check that your profile wallet and at least one test token are ready.
    • Open Developers. Create a test key for that store with invoices.write and invoices.read. Save its profile ID and store ID.
    • Get test tokens and the network’s fee token for your payer wallet. Use exactly the network shown by checkout. Never send real funds.

    2. Set server credentials

    Store these values in your server’s environment. The documentation host, your application host and the API origin are different settings.

    The hosted API address below is the configured application endpoint, not evidence of a production launch. For local development, use http://localhost:8080.

    Shell
    export FORWEND_API_URL=https://forwend.com/api
    export FORWEND_KEY=fw_test_replace_on_your_server
    export FORWEND_PROFILE_ID=replace_with_your_profile_id
    export FORWEND_STORE_ID=replace_with_your_store_id

    3. Create the purchase attempt

    Save this JavaScript as create-checkout.mjs, then run node create-checkout.mjs with Node 20 or later. Calculate the price from your own order records. Never trust an amount supplied by the browser.

    Keep the idempotency key stable when retrying this purchase attempt. Use a new key for a new attempt.

    JavaScript
    const response = await fetch(
      process.env.FORWEND_API_URL + "/v1/profiles/" +
        process.env.FORWEND_PROFILE_ID + "/checkout-sessions",
      {
        method: "POST",
        headers: {
          Authorization: "Bearer " + process.env.FORWEND_KEY,
          "Content-Type": "application/json",
          "Idempotency-Key": "order-1042-attempt-1",
        },
        body: JSON.stringify({
          storeId: process.env.FORWEND_STORE_ID,
          amountUsd: "1250.00",
          reference: "order-1042",
          metadata: { order_id: "1042" },
        }),
      },
    );
    if (!response.ok) throw new Error("Checkout could not be created");
    const session = await response.json();
    // Send only the hosted URL, or the pay token for an embedded checkout, to your browser.
    const hostedUrl = session.payment.hostedUrl;
    const payToken = session.payment.payToken;
    console.log(JSON.stringify({ sessionId: session.sessionId, hostedUrl, livemode: session.payment.livemode }, null, 2));

    4. Open the hosted checkout

    The script prints sessionId, hostedUrl and livemode. Save the sessionId as SESSION_ID in your terminal: export SESSION_ID=the_returned_id. A new attempt returns HTTP 201. An exact retry returns HTTP 200 with the original attempt. The following excerpt shows the fields to use; IDs and the hosted URL come from your response.

    • Open payment.hostedUrl in your browser.
    • Choose an available token/network pair, then send the exact test amount to the displayed receive address.
    • Wait for confirmation. Timing depends on the network; a detected transfer is not a paid order.
    4. Open the hosted checkout
    FieldDetails
    sessionIdstringSave this ID beside your order.
    statusstringThe checkout state: open, complete or expired.
    payment.hostedUrlstring | nullThe customer-facing payment URL. Use the returned URL; do not construct a token.
    payment.livemodebooleanMust be false for this test integration.

    5. Verify completion on your server

    Read the session again with the same store-scoped key. A redirect or browser status callback cannot authorize fulfillment.

    Check the saved session ID, order reference, store, mode, expected amount and token/network identity. Fulfill once only after canonical paymentStatus is paid.

    For unattended orders, verify signed webhooks, queue them durably, deduplicate event IDs, and fetch the current session before fulfilling. Settlement is a separate step.

    Shell
    curl "$FORWEND_API_URL/v1/profiles/$FORWEND_PROFILE_ID/checkout-sessions/$SESSION_ID" \
      -H "Authorization: Bearer $FORWEND_KEY"
    Forwend documentation Test first. Confirm on your server.