Overview
The Checkout API allows you to create payment sessions that redirect customers to a hosted checkout page. This is the simplest way to accept payments — you create a session, redirect the customer, and receive payment confirmation via webhook.
When to Use Checkout
Use Checkout when:
You want a hosted payment page with minimal integration effort
You need to support multiple payment methods without building custom UI
You prefer redirect-based payment flows over embedded forms
Use Payment Intents when:
You need a custom payment UI on your own site
You're building a mobile app with native payment flows
You need fine-grained control over the payment confirmation process
Checkout Flow
Your Server SaligPay API Customer
│ │ │
├── POST /api/checkout ──────►│ │
│◄── sessionToken + URL ──────┤ │
│ │ │
│── Redirect customer ───────────────────────────────────►│
│ │◄── Customer pays ─────────┤
│◄── Webhook notification ────┤ │
│ │──── Redirect to returnUrl ─┤
Quick Start
Step 1: Install and Configure the SDK
npm install saligpay-node
import { SaligPay } from "saligpay-node" ;
const saligpay = new SaligPay ({
clientId: process.env. SALIGPAY_CLIENT_ID ! ,
clientSecret: process.env. SALIGPAY_CLIENT_SECRET ! ,
env: "sandbox" ,
});
await saligpay. authenticate ();
Step 2: Create a Checkout Session
const checkout = await saligpay.checkout. create ({
externalId: "order-123" ,
amount: 10000 , // ₱100.00 in centavos
description: "Premium Plan Subscription" ,
webhookUrl: "https://yourapp.com/webhooks/saligpay" ,
returnUrl: "https://yourapp.com/payment/success" ,
contact: {
name: "John Doe" ,
email: "john@example.com" ,
contact: "+639123456789" ,
},
metadata: { orderId: "12345" },
});
console. log ( "Checkout URL:" , checkout.checkoutUrl);
console. log ( "Session Token:" , checkout.sessionToken);
Step 3: Redirect the Customer
// In your Express route or API handler
res. redirect (checkout.checkoutUrl);
Step 4: Handle the Webhook
Set up a webhook endpoint to receive payment notifications:
app. post ( "/webhooks/saligpay" , async ( req , res ) => {
const payload = req.body;
if (payload.status === "completed" ) {
console. log ( "Payment completed:" , payload.externalId);
// Update order status, send confirmation email, etc.
}
res. status ( 200 ). json ({ received: true });
});
API Reference
Create Checkout Session
POST /api/checkout
Creates a new payment checkout session and returns a checkout URL.
Request
POST /api/checkout
Authorization: Bearer <access_token>
Content-Type: application/json
{
"externalId": "order-123",
"amount": 10000,
"description": "Premium Plan Subscription",
"webhookUrl": "https://yourapp.com/webhooks/saligpay",
"returnUrl": "https://yourapp.com/payment/success",
"contact": {
"name": "John Doe",
"email": "john@example.com",
"contact": "+639123456789"
},
"metadata": { "orderId": "12345" },
"isThirdParty": true
}
Request Fields
Field Type Required Description externalIdstring Yes Unique external reference ID for the order amountnumber Yes Amount in centavos (₱100.00 = 10000) descriptionstring Yes Payment description shown to customer webhookUrlstring Yes URL for payment status notifications returnUrlstring Yes URL to redirect after payment contact.namestring Yes Customer full name contact.emailstring Yes Customer email contact.contactstring No Customer phone number metadataobject No Additional key-value data isThirdPartyboolean No Default: true
Response
{
"success" : true ,
"data" : {
"id" : "checkout_abc123" ,
"sessionToken" : "550e8400-e29b-41d4-a716-446655440000" ,
"amount" : 10000 ,
"fee" : 250 ,
"description" : "Premium Plan Subscription" ,
"checkoutUrl" : "https://checkout.saligpay.com/session/xxx" ,
"expiresAt" : "2025-05-03T13:00:00Z" ,
"status" : "pending" ,
"createdAt" : "2025-05-03T12:00:00Z"
}
}
Get Payment Session
GET /api/checkout/session/:sessionToken
Retrieves details of a specific payment session. Requires admin key authentication.
GET /api/checkout/session/550e8400-e29b-41d4-a716-446655440000
X-Admin-Key: salig-pay-admin-key-2025
Process Payment from Session
POST /api/checkout/process/:sessionToken
Processes payment from a previously created session.
POST /api/checkout/process/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <access_token>
Content-Type: application/json
{
"paymentMethodId": "pm_card_visa"
}
Poll Payment Status
GET /api/checkout/polling/:sessionToken
Polls the status of a payment session.
GET /api/checkout/polling/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <access_token>
SDK Reference
CheckoutResource
The checkout resource provides methods for creating and managing checkout sessions.
create(options)
Creates a new checkout session.
interface CreateCheckoutOptions {
externalId : string ;
amount : number ;
description : string ;
webhookUrl : string ;
returnUrl : string ;
contact : {
name : string ;
email : string ;
contact ?: string ;
};
metadata ?: Record < string , unknown >;
isThirdParty ?: boolean ;
}
interface CreateCheckoutApiResponse {
id : string ;
sessionToken : string ;
amount : number ;
description : string ;
checkoutUrl : string ;
expiresAt : string ;
status : CheckoutStatus ;
createdAt : string ;
}
type CheckoutStatus =
| "pending"
| "processing"
| "completed"
| "failed"
| "cancelled"
| "expired" ;
Usage Example
const checkout = await saligpay.checkout. create ({
externalId: "order-456" ,
amount: 25000 ,
description: "Annual subscription" ,
webhookUrl: "https://yourapp.com/webhooks/saligpay" ,
returnUrl: "https://yourapp.com/success" ,
contact: {
name: "Jane Smith" ,
email: "jane@example.com" ,
},
metadata: { subscriptionType: "annual" },
});
// Redirect customer to checkout
res. redirect (checkout.checkoutUrl);
Error Handling
Common Errors
Error Cause Solution Amount must be at least 1 (in cents)Amount is 0 or negative Ensure amount is a positive integer Session not foundInvalid or expired session token Verify session token and check expiration Invalid access tokenExpired or invalid JWT Refresh authentication token Validation errorMissing required fields Check all required fields are present
Error Response Format
{
"success" : false ,
"message" : "Validation failed" ,
"errors" : [
{
"path" : "amount" ,
"message" : "Amount must be at least 1 cent" ,
"code" : "validation_error"
}
]
}
Handling Errors in Code
try {
const checkout = await saligpay.checkout. create ({
externalId: "order-123" ,
amount: 10000 ,
description: "Payment" ,
webhookUrl: "https://yourapp.com/webhooks/saligpay" ,
returnUrl: "https://yourapp.com/success" ,
contact: { name: "John" , email: "john@example.com" },
});
} catch (error) {
if (error instanceof SaligPay . AuthenticationError ) {
await saligpay. authenticate ();
// Retry the request
} else if (error instanceof SaligPay . ValidationError ) {
console. error ( "Invalid input:" , error.message);
} else {
console. error ( "Checkout failed:" , error.message);
}
}
Best Practices
Security
Always validate amounts server-side before creating checkout sessions
Use HTTPS for all API communications and webhook endpoints
Verify webhook signatures to prevent spoofed notifications
Store externalId securely to prevent duplicate charges
Session Management
Checkout sessions expire after a set period — handle expired sessions gracefully
Use the polling endpoint or webhooks to track payment status
Implement idempotency using externalId to prevent duplicate sessions
Webhook Reliability
Return 200 OK quickly from webhook handlers
Process webhook events asynchronously
Track processed webhook event IDs to handle duplicates
Implement retry logic for failed webhook processing
User Experience
Provide clear payment descriptions so customers know what they're paying for
Use meaningful returnUrl paths (e.g., /payment/success?orderId=123)
Show loading states while redirecting to checkout
Handle payment failures gracefully with clear error messages
Related Guides:
Last modified on May 5, 2026