Skip to main content

Quickstart

This quickstart covers the public server-to-server integration path.

Integration Path

  1. Server-to-server integration flow

Base URL: https://api.sodapopfi.com

  • Build canonical JSON payload per action.
  • Sign request message and send timestamped headers.
  • Use integration endpoints under /integration/*.

Minimum Setup

  1. Select chain and verify it is supported.
  2. Decide token model (native token or ERC-20 tokenAddress).
  3. Implement error handling for 400, 401, 404, and 500 responses.
  4. Track invoice states until completed or withdrawn.

First Successful Calls

For server-to-server:

  1. POST /integration/invoices
  2. GET /integration/invoices/status
  3. Optional: POST /integration/fees/set-meta

End-to-End Example

Create an invoice, hand the payment URL to the customer, and wait for settlement. Generate an API key in the dashboard at https://app.sodapopfi.com/ first.

.env
SODAPOP_BASE_URL=https://api.sodapopfi.com
SODAPOP_API_KEY=<YOUR_API_KEY>
OWNER_ADDRESS=0x501BEF961A6f40E063efD6048768b0BC35ab1428
checkout.ts
import axios from "axios";

const api = axios.create({
baseURL: process.env.SODAPOP_BASE_URL,
headers: {
"Content-Type": "application/json",
"x-depay-api-key": process.env.SODAPOP_API_KEY ?? "",
},
});

const ownerAddress = process.env.OWNER_ADDRESS!;

// 1. Create the invoice — 12.5 USDC on Base.
const { data: invoice } = await api.post("/integration/invoices", {
ownerAddress,
chainId: 8453,
invoiceId: "1000456",
amount: "12.5",
tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
webhookUrl: "https://merchant.example.com/webhooks/invoice",
metadata: { orderId: "1000456" },
});

// 2. Send the customer to the hosted payment page.
// Store paymentAddress on your order — status lookups are keyed by it.
console.log(`Pay here: ${invoice.url}`);

// 3. Poll until the invoice reaches a final state.
// In production prefer the webhook and use polling for reconciliation.
const FINAL = ["completed", "cancelled", "expired"];

while (true) {
const { data } = await api.get("/integration/invoices/status", {
params: { ownerAddress, paymentAddress: invoice.paymentAddress },
});

console.log(data.invoice.status, data.invoice.metaBalance);

if (FINAL.includes(data.invoice.status)) break;

await new Promise((resolve) => setTimeout(resolve, 20_000));
}

Run with npm i axios and Node 20+.

Full per-endpoint examples live in Payment Service API Invoices.

Next Steps