Skip to content

Pattern Examples

This section demonstrates common Gatepay integration patterns using the SDK and API.

This pattern involves periodically checking for payments on your links using the API.

Use the createLink function to create a payment-gated link:

import { Gatepay } from "gatepay-sdk"
const gatepay = new Gatepay({ apiToken: "your-api-token" })
const link = await gatepay.createLink({
name: "Premium Content",
description: "Access to exclusive content",
resource: {
type: "link",
data: {
url: "https://example.com/premium-content",
},
},
toll: {
tollPaymentRequirements: [
{
assetNetwork: "base",
amount: "1000000", // 1 USDC
assetAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
destinationAddress: "your-wallet-address",
},
],
},
})

Use the API to pull payment status for the link:

async function monitorPayments(linkUuid: string) {
const seenPayments = new Set<string>()
setInterval(async () => {
try {
const response = await gatepay.links.getLinksByLinkUuidPayments({
linkUuid,
limit: 50,
page: 1,
})
const newPayments =
response.payments?.filter((payment) => {
if (!seenPayments.has(payment.uuid)) {
seenPayments.add(payment.uuid)
return true
}
return false
}) || []
// Process new payments
for (const payment of newPayments) {
if (payment.status === "confirmed") {
console.log("New payment confirmed:", {
uuid: payment.uuid,
amount: payment.amount,
transactionHash: payment.transactionHash,
})
// Grant user access, update database, etc.
await processPayment(payment)
}
}
} catch (error) {
console.error("Error polling payments:", error)
}
}, 5000) // Poll every 5 seconds
}
// Start monitoring
monitorPayments(link.uuid)

This pattern is useful for server-side integrations where you want to control access or trigger logic after confirming payment.

This pattern uses webhooks to receive real-time notifications when payments are completed.

Set up a Hono server with a POST handler to receive payment notifications:

import { Hono } from "hono"
const app = new Hono()
app.post("/webhooks/payment-completed", async (c) => {
// Verify webhook secret
const authHeader = c.req.header("Authorization")
if (authHeader !== `Bearer ${process.env.WEBHOOK_SECRET}`) {
return c.text("Unauthorized", 401)
}
const payload = await c.req.json()
if (payload.event === "payment.completed") {
const { payment, link, user } = payload
console.log("Payment webhook received:", {
paymentUuid: payment.uuid,
amount: payment.amount,
transactionHash: payment.transactionHash,
userWallet: user.walletAddress,
})
// Process the payment
await processPaymentWebhook(payload)
}
return c.text("OK", 200)
})
async function processPaymentWebhook(payload: any) {
// Grant user access
// Update database
// Send confirmation email
// Trigger business logic
console.log(`Processing payment for user: ${payload.user.walletAddress}`)
}
export default app

First create the link, then add the callback action:

// Create the link
const link = await gatepay.createLink({
name: "Premium Service",
description: "Access to premium service with webhook notifications",
resource: {
type: "redirect",
data: {
url: "https://premium.example.com/dashboard",
},
},
toll: {
tollPaymentRequirements: [
{
assetNetwork: "base",
amount: "5000000", // 5 USDC
assetAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
destinationAddress: "your-wallet-address",
},
],
},
})
// Add callback action
await gatepay.links.postLinksByLinkUuidActions({
linkUuid: link.uuid,
postLinksByLinkUuidActionsRequest: {
type: "callback",
data: {
url: "https://your-server.com/webhooks/payment-completed",
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer your-webhook-secret",
"X-Event-Type": "payment.completed",
},
},
},
})

Gatepay will POST to your endpoint when a payment is confirmed, allowing you to automate business logic in real-time.

Pattern 3: Hybrid Approach (Webhooks + Polling Fallback)

Section titled “Pattern 3: Hybrid Approach (Webhooks + Polling Fallback)”

Combine both patterns for maximum reliability:

class PaymentMonitor {
private seenPayments = new Set<string>()
private gatepay: Gatepay
constructor(apiToken: string) {
this.gatepay = new Gatepay({ apiToken })
}
async createLinkWithMonitoring(linkConfig: any) {
// Create link
const link = await this.gatepay.createLink(linkConfig)
// Add webhook
await this.gatepay.links.postLinksByLinkUuidActions({
linkUuid: link.uuid,
postLinksByLinkUuidActionsRequest: {
type: "callback",
data: {
url: "https://your-server.com/webhooks/payment",
method: "POST",
headers: {
Authorization: "Bearer webhook-secret",
},
},
},
})
// Start polling as fallback
this.startPolling(link.uuid)
return link
}
private startPolling(linkUuid: string) {
setInterval(async () => {
try {
const response =
await this.gatepay.links.getLinksByLinkUuidPayments({
linkUuid,
limit: 10,
})
// Process any payments not already seen
const newPayments =
response.payments?.filter(
(p) =>
!this.seenPayments.has(p.uuid) &&
p.status === "confirmed"
) || []
newPayments.forEach((payment) => {
this.seenPayments.add(payment.uuid)
this.processPayment(payment)
})
} catch (error) {
console.error("Polling error:", error)
}
}, 30000) // Poll every 30 seconds as fallback
}
private async processPayment(payment: any) {
console.log("Processing payment:", payment.uuid)
// Your business logic here
}
}

This approach provides webhook speed with polling reliability as a backup.


See also: