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 typeWhen thrown
MyPOSConfigErrorMissing or invalid client configuration (e.g., missing storeId)
MyPOSSignatureErrorNotification 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
  }
}