// 1. Create Checkout Session
const response = await fetch('https://pay.pingpay.io/api/checkout/sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY', // Get this from your PingPay dashboard
},
body: JSON.stringify({
amount: '1000000', // 1 USDC (6 decimals: 1 * 10^6 = 1000000)
asset: {
chain: 'NEAR',
symbol: 'USDC',
},
successUrl: 'https://yoursite.com/success',
cancelUrl: 'https://yoursite.com/cancel',
}),
});
const { sessionUrl, session } = await response.json();
// Redirect user to checkout page
window.location.href = sessionUrl;
// 2. Create Webhook Endpoint (one-time setup)
const webhookResponse = await fetch('https://pay.pingpay.io/api/rpc/webhooks.createEndpoint', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
body: JSON.stringify({
url: 'https://yoursite.com/webhooks/pingpay',
events: [
'payment.success',
'payment.failed'
],
}),
});
const { endpoint, secret } = await webhookResponse.json();
// Save the secret securely - you'll need it to verify webhook signatures
console.log('Webhook endpoint created:', endpoint.id);
console.log('Webhook secret:', secret); // Store this securely!
// 3. Verify Webhook Signature (Node.js/Express example)
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
timestamp: string,
signature: string,
secret: string
): boolean {
const signaturePayload = `${timestamp}.${payload}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signaturePayload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// 4. Handle Webhook Events (Express.js example)
app.post('/webhooks/pingpay', express.raw({ type: 'application/json' }), (req, res) => {
const payload = req.body.toString('utf8');
const timestamp = req.headers['x-ping-timestamp'];
const signature = req.headers['x-ping-signature'];
const eventType = req.headers['x-ping-event-type'];
// Verify signature
if (!verifyWebhookSignature(payload, timestamp, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(payload);
// Handle different event types
switch (eventType) {
case 'payment.success':
// Payment completed successfully
console.log('Payment successful:', event.data.paymentId);
// Update your database, send confirmation email, etc.
break;
case 'payment.failed':
// Payment failed or was refunded
console.log('Payment failed:', event.data.paymentId);
// Notify customer, handle refund logic, etc.
break;
}
res.status(200).send('Webhook received');
});