Skip to content

Payment Verification

We encourage you to verify payments on your server. This ensures that the payment was not tampered with in the browser, and that the payment was actually sent to your wallet. This is especially important if you are selling digital goods or services.

Use the following example to create a payment intent on your server and then show a button for that intent on the browser. You can then forward the user to a success page that includes the intent, which you can verify.

INFO

If you need real-time payment events, see the Payment Events example.

Payment Intent Example

The full example code can be found on GitHub.

js
import * as code from "@code-wallet/client";
import express from "express";

const app = express();

// ...

// Create intent (notify the Code Sequencer that you want to receive a payment)
app.post('/create-intent', async (req, res) => {
  const { clientSecret, id } = await code.paymentIntents.create({
    amount: 0.05, // Minimum amount is $0.05 USD
    currency: 'usd',
    destination: 'E8otxw1CVX9bfyddKu3ZB3BVLa4VVF9J7CTPdnUwT9jR',
  });

  console.log('Created intent', id);

  // This value needs to be sent to the browser so that the browser can use it
  // to setup a payment with this intent instance.
  res.send({ clientSecret });
});

// Verify intent (verify that the payment was sent to your wallet)
app.get('/verify/:id', async (req, res) => {
  
  const intent = req.params.id;
  const { status } = await code.paymentIntents.getStatus({ intent });

  // ...
});
import * as code from "@code-wallet/client";
import express from "express";

const app = express();

// ...

// Create intent (notify the Code Sequencer that you want to receive a payment)
app.post('/create-intent', async (req, res) => {
  const { clientSecret, id } = await code.paymentIntents.create({
    amount: 0.05, // Minimum amount is $0.05 USD
    currency: 'usd',
    destination: 'E8otxw1CVX9bfyddKu3ZB3BVLa4VVF9J7CTPdnUwT9jR',
  });

  console.log('Created intent', id);

  // This value needs to be sent to the browser so that the browser can use it
  // to setup a payment with this intent instance.
  res.send({ clientSecret });
});

// Verify intent (verify that the payment was sent to your wallet)
app.get('/verify/:id', async (req, res) => {
  
  const intent = req.params.id;
  const { status } = await code.paymentIntents.getStatus({ intent });

  // ...
});
html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Code SDK - Example/3-minimal-with-verify</title>
</head>

<body>
  <div id="button-container"></div>

  <script type="module">
    import code from 'https://js.getcode.com/v1';

    const { button } = code.elements.create('button', {
      currency: 'usd',
      destination: 'E8otxw1CVX9bfyddKu3ZB3BVLa4VVF9J7CTPdnUwT9jR',
      amount: 0.05, // Minimum amount is $0.05 USD
      confirmParams: {
        success: {
          // The URL to redirect to after a successful payment. The
          // {{INTENT_ID}} placeholder will be filled in automatically.

          url: '/verify/{{INTENT_ID}}',
        },

        // You can optionally specify a cancel URL to redirect to if the user
        // cancels the payment on either their Code app or on the browser.

        // cancel: { url: '...' }
      },
    });

    button.on('invoke', async () => {
      // This is called when the "Pay with Code" button is clicked.

      // Get a payment intent from our own server. We're not just going to trust
      // the front-end to charge the correct amount and to the correct
      // destination.
      const res = await fetch('/create-intent', { method: 'POST' });
      const { clientSecret } = await res.json();

      // Update the button with the new client secret generated by the server.
      button.update({ clientSecret });

      // return true; // Return true to cancel the payment intent (if needed)
    })

    button.mount('#button-container');
  </script>
</body>

</html>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Code SDK - Example/3-minimal-with-verify</title>
</head>

<body>
  <div id="button-container"></div>

  <script type="module">
    import code from 'https://js.getcode.com/v1';

    const { button } = code.elements.create('button', {
      currency: 'usd',
      destination: 'E8otxw1CVX9bfyddKu3ZB3BVLa4VVF9J7CTPdnUwT9jR',
      amount: 0.05, // Minimum amount is $0.05 USD
      confirmParams: {
        success: {
          // The URL to redirect to after a successful payment. The
          // {{INTENT_ID}} placeholder will be filled in automatically.

          url: '/verify/{{INTENT_ID}}',
        },

        // You can optionally specify a cancel URL to redirect to if the user
        // cancels the payment on either their Code app or on the browser.

        // cancel: { url: '...' }
      },
    });

    button.on('invoke', async () => {
      // This is called when the "Pay with Code" button is clicked.

      // Get a payment intent from our own server. We're not just going to trust
      // the front-end to charge the correct amount and to the correct
      // destination.
      const res = await fetch('/create-intent', { method: 'POST' });
      const { clientSecret } = await res.json();

      // Update the button with the new client secret generated by the server.
      button.update({ clientSecret });

      // return true; // Return true to cancel the payment intent (if needed)
    })

    button.mount('#button-container');
  </script>
</body>

</html>

This snippet creates a payment button that looks like this: