After setting up the SDK, you can initiate payments. The Payment Link method is recommended for most website integrations.
Payment Methods Overview
Method Use Case User Experience Best For Payment Link E-commerce, websites Redirects to hosted payment page, returns to your site Most integrations (React, Next.js, etc.) User Payment Account holders or new users Redirects to AcountPay portal Subscriptions, repeat customers Direct Bank Payment Simple integrations Redirects directly to bank authentication Basic payment buttons
Payment Link Method (Recommended)
Creates a payment and returns a URL to AcountPay’s hosted payment page. The customer selects their bank there, authenticates the payment, and is redirected back to your redirectUrl with a ?status=success|failed|pending query parameter.
Parameter Type Required Description amountnumber✅ Yes Payment amount in major currency units (e.g., 10.50) referenceNumberstring✅ Yes Unique reference number (your order ID) redirectUrlstring✅ Yes URL to return the customer to after payment descriptionstring❌ No Description shown to the customer during payment currencystring❌ No Currency code (default: DKK) webhookUrlstring❌ No Server-side URL to receive payment status updates
const acount = new Acount ({
clientId: 'your-client-id'
});
const { redirectUrl } = await acount . createPaymentLink ({
amount: 99.99 ,
referenceNumber: 'ORDER-123' ,
redirectUrl: 'https://your-website.com/payment-callback' ,
});
// Send the customer to the payment page
window . location . href = redirectUrl ;
<! DOCTYPE html >
< html >
< head >
< script src = "https://cdn.acountpay.com/sdk/acount.umd.js" ></ script >
</ head >
< body >
< button onclick = " pay ()" > Pay with AcountPay </ button >
< script >
async function pay () {
const acount = new Acount ({
clientId: 'your-client-id'
});
try {
const { redirectUrl } = await acount . createPaymentLink ({
amount: 99.99 ,
referenceNumber: 'ORDER-123' ,
redirectUrl: window . location . origin + '/payment-callback' ,
});
window . location . href = redirectUrl ;
} catch ( error ) {
console . error ( 'Payment failed:' , error );
alert ( 'Could not start payment. Please try again.' );
}
}
</ script >
</ body >
</ html >
With Webhook (Server-to-Server Status Updates)
const { redirectUrl , paymentId } = await acount . createPaymentLink ({
amount: 99.99 ,
referenceNumber: 'ORDER-123' ,
redirectUrl: 'https://your-website.com/payment-callback?orderId=123' ,
webhookUrl: 'https://your-website.com/api/acountpay-webhook' ,
description: 'Order #123 - Blue Widget' ,
});
window . location . href = redirectUrl ;
Your webhook endpoint will receive a POST with { status, referenceNumber, amount, currency } when the payment status changes.
User Payment Method
For users with AcountPay accounts or those who want to create one.
Parameter Type Required Description amountnumber✅ Yes Payment amount in major currency units (e.g., 10.50 = $10.50) requestIdstring✅ Yes Unique request identifier (your order ID) callbackURLstring✅ Yes URL the user is returned to after the payment flow
const acount = new Acount ({
clientId: 'your-client-id'
});
await acount . initiateUserPaymentByEmail ({
amount: 99.99 ,
requestId: 'ORDER-' + orderId ,
callbackURL: 'https://your-website.com/payment-callback'
});
<! DOCTYPE html >
< html >
< head >
< script src = "https://cdn.acountpay.com/sdk/acount.umd.js" ></ script >
</ head >
< body >
< button onclick = " payAsUser ()" > Pay with AcountPay Account </ button >
< script >
async function payAsUser () {
const acount = new Acount ({
clientId: 'your-client-id'
});
try {
await acount . initiateUserPaymentByEmail ({
amount: 99.99 ,
requestId: 'ORDER-123' ,
callbackURL: 'https://your-website.com/payment-success'
});
} catch ( error ) {
console . error ( 'Payment failed:' , error );
alert ( 'Payment could not be initiated. Please try again.' );
}
}
</ script >
</ body >
</ html >
Direct Bank Payment Method
Redirects the customer directly to Token.io’s hosted bank authentication page. The customer is redirected away from your site. After payment, the backend redirects the customer to the merchant’s registered website URL.
For most website integrations, use createPaymentLink instead. It gives you control over the return URL and supports webhooks.
Parameter Type Required Description amountnumber✅ Yes Payment amount in major currency units referenceNumberstring✅ Yes Unique reference number (your order ID) currencystring❌ No Currency code (default: DKK)
const acount = new Acount ({
clientId: 'your-client-id'
});
await acount . initiatePayment ({
amount: 99.99 ,
referenceNumber: 'ORDER-123' ,
});
// Customer is redirected to bank authentication
Framework Integration Examples
// components/PaymentButton.tsx
'use client' ;
import { useState } from 'react' ;
import AcountPay from '@acountpay/pis-sdk' ;
export function PaymentButton ({ amount , orderId } : { amount : number ; orderId : string }) {
const [ loading , setLoading ] = useState ( false );
const handlePayment = async () => {
setLoading ( true );
try {
const acount = new AcountPay ({
clientId: process . env . NEXT_PUBLIC_ACOUNTPAY_CLIENT_ID !
});
const { redirectUrl } = await acount . createPaymentLink ({
amount ,
referenceNumber: orderId ,
redirectUrl: ` ${ window . location . origin } /payment-callback?orderId= ${ orderId } ` ,
});
window . location . href = redirectUrl ;
} catch ( error ) {
console . error ( 'Payment failed:' , error );
setLoading ( false );
alert ( 'Could not start payment. Please try again.' );
}
};
return (
< button
onClick = { handlePayment }
disabled = { loading }
className = "w-full bg-blue-600 text-white py-3 px-6 rounded-lg"
>
{ loading ? 'Processing...' : 'Pay with AcountPay' }
</ button >
);
}
Handle the callback: // app/payment-callback/page.tsx
'use client' ;
import { useSearchParams } from 'next/navigation' ;
export default function PaymentCallback () {
const searchParams = useSearchParams ();
const status = searchParams . get ( 'status' );
const orderId = searchParams . get ( 'orderId' );
if ( status === 'success' ) {
return < div > Payment successful ! Order { orderId } confirmed . </ div > ;
}
if ( status === 'failed' ) {
return < div > Payment failed . < a href = "/checkout" > Try again < /a></ div > ;
}
return < div > Payment is processing . We 'll notify you when it completes.</div> ;
}
Environment Variables: # .env.local
NEXT_PUBLIC_ACOUNTPAY_CLIENT_ID = your-client-id
// components/PaymentButton.tsx
import { useState } from 'react' ;
import AcountPay from '@acountpay/pis-sdk' ;
export function PaymentButton ({ amount , orderId } : { amount : number ; orderId : string }) {
const [ loading , setLoading ] = useState ( false );
const handlePayment = async () => {
setLoading ( true );
try {
const acount = new AcountPay ({
clientId: process . env . REACT_APP_ACOUNTPAY_CLIENT_ID !
});
const { redirectUrl } = await acount . createPaymentLink ({
amount ,
referenceNumber: orderId ,
redirectUrl: ` ${ window . location . origin } /payment-callback?orderId= ${ orderId } ` ,
});
window . location . href = redirectUrl ;
} catch ( error ) {
console . error ( 'Payment failed:' , error );
setLoading ( false );
alert ( 'Could not start payment. Please try again.' );
}
};
return (
< button
onClick = { handlePayment }
disabled = { loading }
className = "w-full bg-blue-600 text-white py-3 px-6 rounded-lg"
>
{ loading ? 'Processing...' : 'Pay with AcountPay' }
</ button >
);
}
Environment Variables: # .env
REACT_APP_ACOUNTPAY_CLIENT_ID = your-client-id
< template >
< button @ click = " handlePayment " : disabled = " loading " >
{{ loading ? 'Processing...' : 'Pay with AcountPay' }}
</ button >
</ template >
< script >
export default {
name: 'PaymentButton' ,
props: {
amount: { type: Number , required: true },
orderId: { type: String , required: true }
} ,
data () {
return { loading: false };
} ,
methods: {
async handlePayment () {
this . loading = true ;
try {
const acount = new window . Acount ({
clientId: process . env . VUE_APP_ACOUNTPAY_CLIENT_ID
});
const { redirectUrl } = await acount . createPaymentLink ({
amount: this . amount ,
referenceNumber: this . orderId ,
redirectUrl: ` ${ window . location . origin } /payment-callback?orderId= ${ this . orderId } ` ,
});
window . location . href = redirectUrl ;
} catch ( error ) {
console . error ( 'Payment failed:' , error );
this . loading = false ;
alert ( 'Could not start payment. Please try again.' );
}
}
}
} ;
</ script >
Environment Variables: # .env
VUE_APP_ACOUNTPAY_CLIENT_ID = your-client-id
Flow Overview
Payment Link Flow (Recommended)
SDK Initialization : Initialize with your Client ID
Create Payment Link : SDK calls AcountPay backend, receives a hosted payment page URL
Redirect : Customer is sent to AcountPay’s payment page
Bank Selection : Customer selects their bank on the payment page
Bank Authentication : Customer authenticates with their bank (SCA)
Return : Customer is redirected back to your redirectUrl with ?status=success|failed|pending
Webhook (optional): Your server receives a POST with the payment status
SDK Initialization : Initialize with your Client ID
Payment Request : SDK calls backend with payment details
User Portal : Browser redirects to AcountPay user portal where user:
Creates account or logs in
Links IBAN to their account
Authenticates and consents to payment
Return : User is redirected back to your callbackURL
SDK Initialization : Initialize with your Client ID
Payment Creation : SDK creates a payment on the backend
Redirect : Customer is sent directly to Token.io’s bank authentication page
Bank Authentication : Customer authenticates with their bank
Return : Customer is redirected to the merchant’s registered website URL
Error Handling
try {
const { redirectUrl } = await acount . createPaymentLink ({
amount: 99.99 ,
referenceNumber: 'ORDER-123' ,
redirectUrl: 'https://your-website.com/payment-callback' ,
});
window . location . href = redirectUrl ;
} catch ( error ) {
console . error ( 'Payment error:' , error );
// Show user-friendly error message
alert ( 'Could not start payment. Please try again.' );
}
On your callback page, check the status query parameter:
const params = new URLSearchParams ( window . location . search );
const status = params . get ( 'status' );
if ( status === 'success' ) {
// Payment completed successfully
} else if ( status === 'failed' ) {
// Payment failed - offer retry
} else if ( status === 'pending' ) {
// Payment is processing - check back later
}
Important Implementation Notes
// ✅ Use actual values
const acount = new Acount ({
clientId: "682ad984-e692-4438-8503-b7e8b6ca1f94"
});
const { redirectUrl } = await acount . createPaymentLink ({
amount: cartTotal ,
referenceNumber: orderId ,
redirectUrl: ` ${ window . location . origin } /order-confirmation?id= ${ orderId } ` ,
});
Use major currency units (e.g., 10.50 for $10.50)
Don’t use smallest currency units (cents/pence)
Ensure amounts match your actual transaction values
Reference Number Best Practices
Use your internal order ID or transaction reference
Ensure uniqueness to avoid duplicate payments
This allows matching successful payments back to orders
Testing
Use your sandbox Client ID from the dashboard
Test the payment link flow end-to-end
Verify your callback page handles all status values (success, failed, pending)
If using webhooks, verify your webhook endpoint receives status updates