StackupDocs
Stackup

Introduction

Simple crypto payment gateway with no smart contracts where funds go directly to merchant

Stackup Pay is a cryptocurrency payment gateway. What makes it different is simplicity with no smart contract layer. Funds go directly to the merchant and we're the only provider that does this.


Approach

To accept payments with Stackup Pay, you only need three things:

  1. Create a Product that defines price, chain/token, and payout destination
  2. Create a Checkout session to get a hosted URL for that product
  3. Get outcomes via Notifications so you can fulfill (payment.succeeded)

Quick Start

We'll create a product, generate a checkout link, and handle a payment event.


1. Create the client

First, we'll create the Stackup client. Log in to Stackup to get your API key.

import { createStackup } from "@stackup-fi/sdk";

const { client } = createStackup({
  accessToken: process.env.STACKUP_API_KEY!,
});

Let’s install our dependencies.

bun add @stackup-fi/sdk

2. Add a product

We'll create a product where we're expecting to be paid in USDC on Base.

const product = await client.product.create({
  payoutWalletAddress: "0x1234567890123456789012345678901234567890",
  chain: "8453",
  currency: "USDC",
  amount: 100,
});

This will create a product that we'll use in next step to create a checkout to accept payment for our product.

3. Generate a checkout session URL

Now it's time to accept payment for our product. We'll use the product ID to create a checkout session.

const checkout = await client.checkout.session.create({
  items: [{ product: product.data.id }],
});

console.log(checkout.data.url);

Here we are generating a checkout session URL. A Customer record will be created automatically from the buyer's wallet address during checkout.

4. Get notified

Create a webhook endpoint in Stackup, and after you get the signing secret, store it as WEBHOOK_SECRET.

Stackup signs webhook payloads with an HMAC, we provide a notify helper that validates the signature for you. For manual verification, see Security.

import { notify } from "@stackup-fi/sdk";

export const handler = notify({
  mode: "webhook",
  secret: process.env.WEBHOOK_SECRET!,
  handler: async (event) => {
    if (event.type === "payment.succeeded") {
      console.log("Payment received:", {
        event,
      });
    }
  },
});

That's it! You're ready to accept payments.