PayFacto API - v2.0 - Solution : Secure Pay By Link (SPL)
PayFacto API - v2.0 - Solution : Secure Pay By Link (SPL)
Secure Pay By Link (SPL) lets you create a payment link and share it with a customer at any time β by email, SMS, QR code, or any other channel. When the customer follows the link, a PayFacto-hosted page opens and an SHC session starts automatically. The customer enters their card details and the payment is processed without you handling any card data.
When to Use SPL
π§
Invoice by email
Create a payment link, drop it into an invoice email. The customer clicks and pays in their browser.
π±
SMS / messaging
Send the link via SMS or WhatsApp. Works on any device with a browser.
β¨οΈ
In-person QR code
Generate a QR code from the link. Print it on a receipt, counter card, or sign.
How It Works
π
Your server creates a payment link
POST to /secure-hosted-checkout/v1/links with the transaction type, amount, and any options. The response contains a linkUrl β this is what you share with the customer.
π§
You share the link with the customer
Embed the linkUrl in an email, SMS, button, or QR code. The link can be used immediately or at any future time, up to the expires date.
π³
Customer follows the link and pays
When the customer opens the link, PayFacto's hosted page loads and an SHC session starts automatically. The customer enters their card details and clicks Pay.
β
PayFacto processes the payment
PayFacto charges the card and redirects the customer to your successUrl or declineUrl. You can also retrieve results via the helper endpoints or webhook.
π
API Key
SPL uses the same API key as SHC and SHP. Base64-encode username:password and pass it as Authorization: Basic ... on every server-side request. Never expose it in client-side code.
π
HTTPS server
Your server must support HTTPS. All PayFacto endpoints require a secure connection.
2
Step 1 β Create a Payment Link
βΉοΈ
Call POST /secure-hosted-checkout/v1/links from your server. The response contains a linkUrl that you share with the customer. The link remains valid until it expires or reaches its usage limit.
β οΈ
Make this call from your server, not the browser. The Authorization header contains your API secret.
Request body β required fields
| Field | Type | Description |
|---|
| transactionType | string Β· required | The type of transaction the customer will perform. PURCHASE β charge immediately. PREAUTHORIZATION β reserve funds, capture later. VERIFY β validate the card only, no money moves. PURCHASE and PREAUTHORIZATION also require purchaseAmount. |
Request body β optional fields
| Field | Type / Default | Description |
|---|
| purchaseAmount | integer | Amount in the smallest currency unit (cents). $10.25 = 1025. Mandatory when transactionType is PURCHASE or PREAUTHORIZATION. This amount is what gets charged β the customer cannot change it on the hosted page unless amount is set to true. |
| language | string Β· default en | Language for the hosted page. en = English, fr = French. |
| description | string Β· max 60 chars | A short description of the payment link. Shown on the hosted page and stored with the link record. |
| invoiceNumber | string Β· max 25 chars | Pre-fill the invoice number on the hosted page. |
| amount | boolean Β· default false | Set true to show an editable amount field on the hosted page. Only use this when you want the customer to enter or confirm the amount themselves. |
| avs | string Β· default none | Show address verification fields. address (street only), postal (postal code only), or both. |
| email | boolean Β· default false | Show an email address field. If the customer fills it in, PayFacto sends them a receipt automatically. |
| expires | string (ISO-8601) | When the link stops working. Format: YYYY-MM-DDTHH:MM:SS.000Z. Default: 5 minutes from creation. Set a longer expiry for links sent by email or SMS. |
| uses | integer Β· default 1 | Maximum number of times the link can be used. Increase for reusable links (e.g. a recurring payment request). Each use creates a separate transaction. |
| successUrl | string (URL) | Where to redirect the customer after a successful payment. |
| declineUrl | string (URL) | Where to redirect the customer after a failed payment or decline. |
| webhookUrl | string (URL) | An extra HTTPS URL that PayFacto will POST the transaction result to after each use. |
JSON β Minimal request body
{
"transactionType": "PURCHASE",
"purchaseAmount": 1025,
"language": "en"
}JavaScript β Create a link (server-side)
const endpoint = 'https://uat.ca.shc.payfacto.cloud/secure-hosted-checkout/v1/links';
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Basic ${Buffer.from('username:password').toString('base64')}`,
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json'
},
body: JSON.stringify({
transactionType: 'PURCHASE',
purchaseAmount: 1025, // $10.25 in cents β mandatory for PURCHASE
language: 'en',
description: 'Invoice #2024-001',
invoiceNumber: 'INV-2024-001',
uses: 1,
expires: '2026-06-30T23:59:59.000Z',
email: true,
successUrl: 'https://your-site.com/paid',
declineUrl: 'https://your-site.com/declined'
})
});
const data = await response.json();
console.log(data.linkUrl); // Share this URL with the customer
3
Step 2 β Read the Response and Share the Link
βΉοΈ
The response echoes back all the fields you sent, plus two new ones: usesUsed (how many times the link has been used) and linkUrl (the full URL to give the customer). The id field is the linkId used in all helper endpoint calls.
| Response field | Description |
|---|
| id | Unique link identifier (linkId). Use this in all helper endpoint calls. |
| linkUrl | The full URL of the hosted payment page. This is what you share with the customer. |
| username | The API username associated with this link. |
| description | Echo of the description you provided, or null. |
| expires | When the link expires in ISO-8601 format. |
| uses | Maximum number of times the link can be used. |
| usesUsed | How many times the link has been used so far. |
| purchaseAmount | The amount that will be charged, in cents. |
| transactionType | Echo of the requested transaction type. |
Ways to share the link
π§
Email
Paste linkUrl into an HTML anchor tag or button in your email template. For plain text, use the GET /browser/links/{{linkId}}/url helper to retrieve just the URL.
π±
SMS / messaging
Use linkUrl directly as the message body or shortened with your preferred URL shortener.
β¨οΈ
QR code
Call GET /browser/links/{{linkId}}/qrcode to get a PNG image of a QR code that opens the hosted page. Embed it in a PDF invoice, print it on a receipt, or display it on a screen.
βΉοΈ
When the customer follows the link, PayFacto's hosted page opens in their browser and an SHC session starts automatically. The page displays the card form with the fields you configured. The customer enters their card details and clicks Pay.
| Step | What happens |
|---|
| Customer opens the link | The hosted page loads. PayFacto starts an SHC session scoped to this link. The form shows the fields you configured when creating the link. |
| Customer fills in the form | Card number, expiry, CVV, and any optional fields (email, address, amount) are entered directly into the PayFacto iframe β your server never sees this data. |
| Customer clicks Pay | PayFacto processes the transaction. 3D Secure runs automatically if your account is configured for it. |
| Payment succeeds | The customer is redirected to your successUrl (if set) or shown a confirmation page. A receipt email is sent if the customer provided their email. |
| Payment fails | The customer is redirected to your declineUrl (if set) or shown an error message with the option to retry. |
| Link is used up | If uses = 1 (default), the link is consumed after the first successful payment. Further attempts show an expiry message. |
β οΈ
If expires has passed or uses has been reached, the hosted page shows an error. Always set a realistic expires value when sending links by email β the default 5-minute window is too short for asynchronous delivery.
βΉοΈ
Use these endpoints to manage links after creation. All use the linkId returned in the create response (the id field).
| Endpoint | Method | Description |
|---|
| /links/{linkId} | GET | Retrieve the current state of a link. Returns the same fields as the create response, including current usesUsed. |
| /links/{linkId}/cancel | POST | Expire a link immediately. No request body required. Use this if the payment is no longer needed or the link was sent to the wrong customer. |
| /links/{linkId}/responses | GET | Get all response objects recorded against this link. Use this to retrieve the transaction result after the customer pays. |
| /links/{linkId}/transactions | GET | Get all transactions created from this link. |
| /browser/links/{linkId}/url | GET | Returns the hosted-page URL as plain text. Useful for embedding in plain-text emails, SMS messages, or building your own QR code. |
| /browser/links/{linkId}/qrcode | GET | Returns a QR code image (PNG) that opens the hosted payment page. Embed directly in an HTML img tag, include in a PDF invoice, or print for in-person use. |
Endpoints β base URL prefix (UAT)
Base: https://uat.ca.shc.payfacto.cloud/secure-hosted-checkout/v1
GET /links/{linkId} β current link state
POST /links/{linkId}/cancel β expire the link immediately
GET /links/{linkId}/responses β all payment responses
GET /links/{linkId}/transactions β all transactions
GET /browser/links/{linkId}/url β hosted page URL (plain text)
GET /browser/links/{linkId}/qrcode β QR code image (PNG)
π‘
To confirm a payment was successful, call GET /links/{{linkId}}/responses from your server after the customer is redirected to your successUrl. Never fulfil an order based on the browser redirect alone.