Quickstart
This quickstart covers the public server-to-server integration path.
Integration Path
- 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
- Select chain and verify it is supported.
- Decide token model (native token or ERC-20
tokenAddress). - Implement error handling for 400, 401, 404, and 500 responses.
- Track invoice states until
completedorwithdrawn.
First Successful Calls
For server-to-server:
POST /integration/invoicesGET /integration/invoices/status- 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
- TypeScript
- Python
- cURL
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+.
checkout.py
import os
import time
import requests
BASE_URL = os.environ["SODAPOP_BASE_URL"].rstrip("/")
OWNER_ADDRESS = os.environ["OWNER_ADDRESS"]
session = requests.Session()
session.headers.update(
{
"Content-Type": "application/json",
"x-depay-api-key": os.environ["SODAPOP_API_KEY"],
}
)
# 1. Create the invoice — 12.5 USDC on Base.
response = session.post(
f"{BASE_URL}/integration/invoices",
json={
"ownerAddress": OWNER_ADDRESS,
"chainId": 8453,
"invoiceId": "1000456",
"amount": "12.5",
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"webhookUrl": "https://merchant.example.com/webhooks/invoice",
"metadata": {"orderId": "1000456"},
},
timeout=30,
)
response.raise_for_status()
invoice = response.json()
# 2. Send the customer to the hosted payment page.
# Store paymentAddress on your order — status lookups are keyed by it.
print(f"Pay here: {invoice['url']}")
# 3. Poll until the invoice reaches a final state.
# In production prefer the webhook and use polling for reconciliation.
FINAL = {"completed", "cancelled", "expired"}
while True:
status = session.get(
f"{BASE_URL}/integration/invoices/status",
params={
"ownerAddress": OWNER_ADDRESS,
"paymentAddress": invoice["paymentAddress"],
},
timeout=30,
)
status.raise_for_status()
current = status.json()["invoice"]
print(current["status"], current["metaBalance"])
if current["status"] in FINAL:
break
time.sleep(20)
Run with pip install requests and Python 3.9+.
checkout.sh
set -euo pipefail
BASE_URL="${SODAPOP_BASE_URL:-https://api.sodapopfi.com}"
# 1. Create the invoice — 12.5 USDC on Base.
INVOICE=$(curl -sS -X POST "$BASE_URL/integration/invoices" \
-H 'Content-Type: application/json' \
-H "x-depay-api-key: $SODAPOP_API_KEY" \
-d '{
"ownerAddress": "'"$OWNER_ADDRESS"'",
"chainId": 8453,
"invoiceId": "1000456",
"amount": "12.5",
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"webhookUrl": "https://merchant.example.com/webhooks/invoice"
}')
# 2. Send the customer to the hosted payment page.
# Store paymentAddress on your order — status lookups are keyed by it.
PAYMENT_ADDRESS=$(echo "$INVOICE" | jq -r '.paymentAddress')
echo "Pay here: $(echo "$INVOICE" | jq -r '.url')"
# 3. Poll until the invoice reaches a final state.
while true; do
STATUS=$(curl -sS "$BASE_URL/integration/invoices/status?ownerAddress=$OWNER_ADDRESS&paymentAddress=$PAYMENT_ADDRESS" \
-H "x-depay-api-key: $SODAPOP_API_KEY" | jq -r '.invoice.status')
echo "status: $STATUS"
case "$STATUS" in
completed|cancelled|expired) break ;;
esac
sleep 20
done
Full per-endpoint examples live in Payment Service API Invoices.
Next Steps
- Read Auth and Signatures.
- Read Invoices Lifecycle.
- Continue with API v1 Overview.