Purchase Flow
The hosted checkout flow has three server-side steps: generate signed fields, redirect the customer to the myPOS checkout page, then validate the webhook myPOS sends after payment.
Server-side only: All signing operations use your secret key. Never run this code in a browser or expose credentials to the client.
Initialize the Client
You can initialize using a pre-built config pack object or individual environment variables.
Using a config pack
import { MyPOSClient } from 'mypos-online-checkout'
const client = new MyPOSClient({
storeId: process.env.MYPOS_STORE_ID!,
storePassword: process.env.MYPOS_STORE_PASSWORD!,
keyIndex: Number(process.env.MYPOS_KEY_INDEX!),
privateKey: process.env.MYPOS_PRIVATE_KEY!,
publicKey: process.env.MYPOS_PUBLIC_KEY!,
isSandbox: true,
})
const { MyPOSClient } = require('mypos-online-checkout')
const client = new MyPOSClient({
storeId: process.env.MYPOS_STORE_ID,
storePassword: process.env.MYPOS_STORE_PASSWORD,
keyIndex: Number(process.env.MYPOS_KEY_INDEX),
privateKey: process.env.MYPOS_PRIVATE_KEY,
publicKey: process.env.MYPOS_PUBLIC_KEY,
isSandbox: true,
})
Generate Signed Fields
Call generateCheckoutFields() on your server to produce the hidden form fields needed for the browser redirect. The returned object contains all signed parameters — do not modify them.
const checkoutFields = await client.generateCheckoutFields({
orderId: 'order-20240601-001',
amount: 19.99,
currency: 'EUR',
urlOk: 'https://mystore.example/checkout/success',
urlCancel: 'https://mystore.example/checkout/cancel',
urlNotify: 'https://mystore.example/api/payment/notify',
cartItems: [
{ name: 'Widget', quantity: 1, price: 19.99 },
],
})
const checkoutFields = await client.generateCheckoutFields({
orderId: 'order-20240601-001',
amount: 19.99,
currency: 'EUR',
urlOk: 'https://mystore.example/checkout/success',
urlCancel: 'https://mystore.example/checkout/cancel',
urlNotify: 'https://mystore.example/api/payment/notify',
cartItems: [
{ name: 'Widget', quantity: 1, price: 19.99 },
],
})
Pass checkoutFields to the browser and use them as hidden inputs in an HTML form that POSTs to the myPOS checkout URL. The SDK provides the target URL via client.checkoutUrl.
Validate the Webhook
When the payment completes, myPOS POSTs the result to urlNotify. Validate the signature and read the outcome:
import type { NextRequest } from 'next/server'
export async function POST(req: NextRequest) {
const body = await req.text()
const params = new URLSearchParams(body)
const result = await client.validateNotification(Object.fromEntries(params))
if (result.success) {
const { orderId, amount, currency } = result.data
// Mark order as paid in your database
console.log(`Payment confirmed: ${orderId} — ${amount} ${currency}`)
} else {
console.error('Payment failed:', result.error)
}
return new Response('OK', { status: 200 })
}
export async function POST(req) {
const body = await req.text()
const params = new URLSearchParams(body)
const result = await client.validateNotification(Object.fromEntries(params))
if (result.success) {
const { orderId, amount, currency } = result.data
// Mark order as paid in your database
console.log(`Payment confirmed: ${orderId} — ${amount} ${currency}`)
} else {
console.error('Payment failed:', result.error)
}
return new Response('OK', { status: 200 })
}
Respond with HTTP 200 and body OK — any other response will cause myPOS to retry the notification.
Error Handling
The SDK throws typed errors for configuration and signature problems:
| Error type | When thrown |
|---|---|
MyPOSConfigError | Missing or invalid client configuration (e.g., missing storeId) |
MyPOSSignatureError | Notification signature validation failed |
import { MyPOSClient, MyPOSConfigError, MyPOSSignatureError } from 'mypos-online-checkout'
try {
const checkoutFields = await client.generateCheckoutFields({ /* ... */ })
} catch (err) {
if (err instanceof MyPOSConfigError) {
console.error('Configuration error:', err.message)
} else if (err instanceof MyPOSSignatureError) {
console.error('Signature mismatch — possible tampering:', err.message)
} else {
throw err
}
}
const { MyPOSClient, MyPOSConfigError, MyPOSSignatureError } = require('mypos-online-checkout')
try {
const checkoutFields = await client.generateCheckoutFields({ /* ... */ })
} catch (err) {
if (err instanceof MyPOSConfigError) {
console.error('Configuration error:', err.message)
} else if (err instanceof MyPOSSignatureError) {
console.error('Signature mismatch — possible tampering:', err.message)
} else {
throw err
}
}