Skip to main content
This guide gets you from zero to a working payment flow. You will install the SDK, set up a minimal signer endpoint, and trigger your first checkout.

Prerequisites

  • A Blink merchant account (merchantId and ECDSA P-256 key pair). See Key Generation and Merchant Registration if you don’t have these yet.
  • Node.js >= 18 for the signer endpoint.

1. Install the SDK

npm install @swype-org/checkout

2. Create a signer endpoint

Add a server route that signs payment requests. This minimal Express example covers the essentials:
const express = require('express');
const { randomUUID, createSign } = require('node:crypto');
const fs = require('node:fs');

const app = express();
app.use(express.json());

const MERCHANT_ID = process.env.MERCHANT_ID;
const PRIVATE_KEY_PEM = process.env.MERCHANT_PRIVATE_KEY
  || fs.readFileSync('./private.pem', 'utf8');

app.post('/api/sign-payment', (req, res) => {
  const { amount, chainId, address, token, callbackScheme = null, version = 'v1' } = req.body;

  const idempotencyKey = randomUUID();
  const signatureTimestamp = new Date().toISOString();

  const payloadObject = {
    amount, chainId, address, token,
    idempotencyKey, callbackScheme, signatureTimestamp, version,
  };

  const payload = Buffer.from(JSON.stringify(payloadObject), 'utf8').toString('base64url');

  const signer = createSign('SHA256');
  signer.update(payload);
  signer.end();
  const signature = signer.sign(PRIVATE_KEY_PEM).toString('base64url');

  res.json({
    merchantId: MERCHANT_ID,
    payload,
    signature,
    preview: { amount, chainId, address, token, idempotencyKey },
  });
});

app.listen(3001);
Set your environment variables:
export MERCHANT_ID="your-merchant-uuid"
export MERCHANT_PRIVATE_KEY="$(cat private.pem)"
See Build Your Signer Endpoint for the full implementation with validation, security, and a Python equivalent.

3. Trigger the checkout

Vanilla JavaScript

import { Checkout, CheckoutError, getDisplayMessage } from '@swype-org/checkout';

const checkout = new Checkout({
  signer: '/api/sign-payment',
});

document.getElementById('deposit-btn').addEventListener('click', async () => {
  try {
    const { transfer } = await checkout.requestDeposit({
      amount: 50,
      chainId: 8453,
      address: '0x1a5FdBc891c5D4E6aD68064Ae45D43146D4F9f3a',
      token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    });
    console.log('Transfer complete:', transfer.id, transfer.status);
  } catch (error) {
    if (error instanceof CheckoutError) {
      alert(getDisplayMessage(error));
    }
  }
});

React

import { useBlinkCheckout } from '@swype-org/checkout/react';

function DepositButton() {
  const { status, result, error, displayMessage, requestDeposit } = useBlinkCheckout({
    signer: '/api/sign-payment',
  });

  const handleDeposit = () => {
    requestDeposit({
      amount: 50,
      chainId: 8453,
      address: '0x1a5FdBc891c5D4E6aD68064Ae45D43146D4F9f3a',
      token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    });
  };

  return (
    <>
      <button onClick={handleDeposit} disabled={status === 'signer-loading'}>
        {status === 'signer-loading' ? 'Preparing...' : 'Deposit $50'}
      </button>
      {error && <p className="error">{displayMessage}</p>}
      {result && <p>Transfer {result.transfer.id} complete!</p>}
    </>
  );
}

What’s next

You now have a working checkout flow. To go to production:
1

Generate a production key pair

Key Generation — create ECDSA P-256 keys and store the private key in a secrets manager.
2

Register your merchant account

Merchant Registration — send your public key to Blink.
3

Harden your signer

Signer Endpoint — add request validation, authentication, rate limiting, and CORS.
4

Handle errors gracefully

Error Handling — use CheckoutError codes and getDisplayMessage() in your UI.
5

Run the production checklist

Production Checklist — verify every item before going live.