What is Slice Pay? #

Slice Pay is a payment solution that allows your customers to split their travel purchases into flexible installment plans. Instead of paying the full amount upfront, customers can make a deposit and pay the remainder in scheduled installments leading up to their departure date.

๐Ÿ’ก Perfect for Travel

Slice Pay is specifically designed for the travel industry, helping customers manage their cash flow while securing their bookings early.

Our Lay By Plans #

Slice Pay offers flexible lay-by plans that automatically adjust based on the customer's departure date and purchase amount. The system intelligently creates a payment schedule that works for both the customer and your business.

๐Ÿ—“๏ธ Flexible Scheduling

Payments are automatically scheduled based on departure dates

๐Ÿ’ฐ Deposit Protection

Secure bookings with minimal upfront deposits

๐Ÿ“ฑ Customer Dashboard

Customers can manage their payment plans through our portal

More Information iFrame #

To provide your customers with more information on what Slice is - useful if you want to include an information icon at checkout. See here: https://agents-iframe.slicepay.travel/

About our API #

The Slice Pay API is designed to be simple and developer-friendly. It follows fundamental Web principles and returns HTML responses that can be easily parsed and integrated into your existing workflow.

HTML Responses

Returns structured HTML that's easy to parse and integrate

๐Ÿ›ก๏ธ Secure by Design

Built with security best practices and proper authentication

๐Ÿ“‹ Form-Based

Uses standard HTTP form submission for compatibility

Specification Keywords #

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Authentication #

Slice Pay uses agent-based authentication through secure Agent IDs. Each agent receives a unique identifier that MUST be included in all API requests.

agentId Required

Your personal agent identifier generated by Slice Pay. This acts as your API key.

๐Ÿ” Security Notice

Your Agent ID is confidential and MUST be treated like a password. Anyone with this key can generate payment links on your behalf. Never expose it in client-side code or public repositories.

Example: agentId=agent-bypass-5kyp4y

๐Ÿ’ก Getting Your Agent ID

Contact the Slice Pay team to receive your unique Agent ID for both staging and production environments.

Environments #

Slice Pay provides separate environments for testing and production use. Always develop and test using the staging environment before deploying to production.

๐Ÿงช Staging Environment

For testing and development

https://api.staging.slicepay.travel
Use this environment for all development, testing, and integration work

๐Ÿš€ Production Environment

For live transactions

https://api.slicepay.travel
Only use this environment for live customer transactions

๐Ÿ“ Environment Guidelines

  • Always test thoroughly in staging before going live
  • Use separate Agent IDs for staging and production
  • Monitor your integration in staging for any API changes
  • Keep your production Agent ID secure and rotate it periodically

Staging #

๐Ÿ“ Regular Flow URL

https://api.staging.slicepay.travel/api/test

Embedded Flow URL

https://api.staging.slicepay.travel/api/test/embedded

๐Ÿ”‘ With Example Test Agent ID

https://api.staging.slicepay.travel/api/test?agentId=agent-bypass-5kyp4y

โš™๏ธ With All OPTIONAL Fields

https://api.staging.slicepay.travel/api/test?agentId=agent-bypass-5kyp4y&bookingNotificationUrl=https://example.com/test-callback&redirectUrlSucceeded=https://example.com/succeeded

How do I get set up in staging? #

  1. Provide us with an email for booking successful notifications (email notifications)
  2. Provide us with the domains to allowlist for webhook endpoints and redirect URLs

We will process these details and have you set up within 1 business day. You can contact us via support@slicepay.travel or directly to the Slice Pay developer you are working with.

๐Ÿ“‹ Required Information

  • Email Address: This will receive test notifications when customers successfully complete deposit payments in staging
  • Domain(s): All domains that will host your webhook endpoints and redirect URLs MUST be pre-authorized for security purposes

Production #

๐Ÿ“ Regular Flow URL

https://api.slicepay.travel/api/create-link

Embedded Flow URL

https://api.slicepay.travel/api/create-link/embedded

๐Ÿ”‘ With Your Agent ID

https://api.slicepay.travel/api/create-link?agentId=your-production-agent-id

โš™๏ธ With All OPTIONAL Fields

https://api.slicepay.travel/api/create-link?agentId=your-production-agent-id&bookingNotificationUrl=https://yourdomain.com/webhook&redirectUrlSucceeded=https://yourdomain.com/success

How do I get set up in production? #

  1. Provide us with an email for deposit confirmation notifications
  2. Provide us with the domains to allowlist for bookingNotificationUrl and redirectUrlSucceeded endpoints

We will process these details and have you set up within 1 business day. You can contact us via support@slicepay.travel or directly to the Slice Pay developer you are working with.

๐Ÿ“‹ Required Information

  • Email Address: This will receive notifications when customers successfully complete deposit payments
  • Domain(s): All domains that will host your bookingNotificationUrl webhook endpoints and redirectUrlSucceeded redirect URLs MUST be pre-authorized for security purposes

Webhook Notifications #

Learn how Slice Pay sends webhook notifications to your system when payments are processed successfully. The bookingNotificationUrl parameter allows you to receive real-time notifications when a customer successfully completes a deposit payment through Slice Pay.

โœ… Use Cases

  • Update booking status in your system
  • Send confirmation emails to customers
  • Trigger fulfillment processes
  • Update inventory or availability
  • Generate receipts or invoices

๐Ÿ“‹ Requirements

  • HTTPS endpoint required
  • Domain MUST be pre-authorized
  • MUST return HTTP 200 status
  • Handle duplicate requests
  • Process requests quickly

How It Works #

1. Request Headers

We'll perform a POST request with the following headers:

Content-Type: application/x-www-form-urlencoded
Accept: text/html
X-Request-ID: [unique-id]

The X-Request-ID is a unique random ID generated for each request. Use this as a deduplication ID in case of retries initiated by our systems.

2. Request Body Parameters

We'll pass the following parameters in the request body in NO specific order:

  • agentId - The original agentId that created the link
  • bookingReference - The original bookingReference this payment is related to
  • salePrice - The original salePrice in cents sent through Create Link API
  • currency - The original currency sent through Create Link API
Example Request Body:
bookingReference=12345&agentId=agent-123&salePrice=1000¤cy=AUD
3. Response Requirements

The destination server MUST ALWAYS return the HTTP status code 200 to acknowledge successful receipt of the webhook.

โš ๏ธ Important

Our webhook call represents a fact (an event that a payment has been received), therefore it's not expected to be rejected for any reason. Any response other than HTTP 200 will be considered a failure, and our system MAY retry the webhook delivery with the same parameters.

Implementation Example #

Node.js/Express Webhook Handler
const express = require('express');
const app = express();

// Middleware to parse form data
app.use(express.urlencoded({ extended: true }));

app.post('/webhook/slicepay-notification', (req, res) => {
    try {
        // Extract webhook data
        const { agentId, bookingReference, salePrice, currency } = req.body;
        const requestId = req.headers['x-request-id'];

        console.log('Received Slice Pay webhook:', {
            requestId,
            agentId,
            bookingReference,
            salePrice,
            currency
        });

        // Check for duplicate requests using X-Request-ID
        if (isDuplicateRequest(requestId)) {
            console.log('Duplicate request detected, ignoring');
            return res.status(200).send('OK');
        }

        // Process the payment notification
        // Update your database, send emails, etc.
        updateBookingStatus(bookingReference, 'payment_received');
        sendConfirmationEmail(bookingReference);

        // Always return 200 for successful processing
        res.status(200).send('OK');

    } catch (error) {
        console.error('Webhook processing error:', error);
        // Still return 200 to prevent retries for processing errors
        res.status(200).send('Error processed');
    }
});

function isDuplicateRequest(requestId) {
    // Implement your deduplication logic here
    // You might store processed request IDs in a cache or database
    return false;
}

function updateBookingStatus(bookingReference, status) {
    // Update your booking system
    console.log(`Updating booking ${bookingReference} to ${status}`);
}

function sendConfirmationEmail(bookingReference) {
    // Send confirmation email to customer
    console.log(`Sending confirmation email for booking ${bookingReference}`);
}

Best Practices #

โœ… Do

  • Always return HTTP 200 for successful processing
  • Implement deduplication using X-Request-ID
  • Process webhooks quickly (under 30 seconds)
  • Log all webhook events for debugging
  • Validate the request parameters
  • Use HTTPS for your webhook endpoint

โŒ Don't

  • Return non-200 status codes for processing errors
  • Process the same webhook multiple times
  • Perform long-running operations synchronously
  • Ignore the X-Request-ID header
  • Expose sensitive information in logs
  • Use HTTP (non-secure) endpoints

Security Considerations #

URL Token Validation

For enhanced security, you can include a validation token as part of your bookingNotificationUrl path. This token can be associated with the booking reference, providing an additional layer of authentication that only you know.

Example Implementation:
https://yourdomain.com/webhook/slicepay/{url_encoded_token}

Where url_encoded_token could be:

  • A hash of the booking reference + your secret key
  • A JWT token containing booking metadata
  • A randomly generated token stored in your database

๐Ÿ’ก Important

Ensure your token is properly URL-encoded when constructing the bookingNotificationUrl. Use functions like encodeURIComponent() in JavaScript or equivalent in your preferred language.

Secure Webhook Handler with Token Validation
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.urlencoded({ extended: true }));

// Your secret key for token generation/validation
const SECRET_KEY = process.env.WEBHOOK_SECRET_KEY;

app.post('/webhook/slicepay/:token', (req, res) => {
    try {
        const { token } = req.params;
        const { agentId, bookingReference, salePrice, currency } = req.body;
        const requestId = req.headers['x-request-id'];

        // Validate the token
        if (!validateToken(token, bookingReference)) {
            console.log('Invalid token for booking:', bookingReference);
            return res.status(200).send('Invalid token');
        }

        console.log('Valid webhook received:', {
            requestId,
            agentId,
            bookingReference,
            salePrice,
            currency
        });

        // Check for duplicates
        if (isDuplicateRequest(requestId)) {
            return res.status(200).send('OK');
        }

        // Process the payment
        updateBookingStatus(bookingReference, 'payment_received');
        sendConfirmationEmail(bookingReference);

        res.status(200).send('OK');

    } catch (error) {
        console.error('Webhook error:', error);
        res.status(200).send('Error processed');
    }
});

function validateToken(receivedToken, bookingReference) {
    // Example: Generate expected token using HMAC
    const expectedToken = crypto
        .createHmac('sha256', SECRET_KEY)
        .update(bookingReference)
        .digest('hex');

    // URL decode the received token for comparison
    const decodedToken = decodeURIComponent(receivedToken);

    return crypto.timingSafeEqual(
        Buffer.from(expectedToken),
        Buffer.from(decodedToken)
    );
}

function generateTokenForBooking(bookingReference) {
    // Use this function when creating the bookingNotificationUrl
    const token = crypto
        .createHmac('sha256', SECRET_KEY)
        .update(bookingReference)
        .digest('hex');

    return encodeURIComponent(token);
}

Regular Flow #

The regular flow creates a payment link that redirects customers to our hosted payment page. This is the simplest integration method where customers complete their payment plan setup on our secure platform.

๐Ÿ’ก Quick Integration

Perfect for getting started quickly. Generate a link and redirect your customers to our payment page. Your customers will be redirected to our secure payment page to complete their payment plan setup. For a more integrated experience, see the Embedded Flow.

Generate a payment link for the redirect flow integration. This is the simplest way to integrate Slice Pay - create a link and redirect your customers to our hosted payment page.

API Request #

cURL Example #

cURL Request

                curl --location --request POST 'https://api.staging.slicepay.travel/api/create-link' \
                  --header 'Accept: text/html' \
                  --header 'Content-Type: application/x-www-form-urlencoded' \
                  --data 'salePrice=1000' \
                  --data 'currency=AUD' \
                  --data 'departureDate=2030-10-01' \
                  --data 'agentId=agent-bypass-5kyp4y' \
                  --data 'bookingReference=ABC123'
            

Raw HTTP Example #

HTTP Request

                POST /api/create-link HTTP/1.1
                Host: api.staging.slicepay.travel
                Accept: text/html
                Content-Type: application/x-www-form-urlencoded
                Content-Length: 104

                salePrice=1000&currency=AUD&departureDate=2030-10-01&agentId=agent-bypass-5kyp4y&bookingReference=ABC123
                

Required Headers #

Accept: text/html Required

Accept headers indicate to the server the media types the client accepts as a response. We require the specific text/html value. Catch-all values such as */* are NOT supported.

Content-Type: application/x-www-form-urlencoded Required

Indicates the request fields need to be in the format name1=value&name2=value&name3=value. This is the same media type used by HTML Form Submission requests.

Request Fields #

salePrice Required

Number in cents representing the total amount of the sale.

Precision of 2 digits by default: 10000 โ†’ 100.00 โ†’ $100.00

Example: salePrice=256058 โ†’ $2560.58
currency Required

A 3-letter currency code representing the currency.

Follows ISO 4217 currency codes .

Example: currency=AUD
departureDate Required

The date when the flight departs.

An ISO 8601 date format representing the departure date.

Example: departureDate=2024-03-12
bookingReference Required

The booking reference used to identify the booking related to this payment plan link.

SHOULD be a unique ID per booking within your agency. We'll use this to query you for more information about the booking.

You can generate multiple payment plan links for the same bookingReference.

Limited to 20 characters long using UTF-8 encoding.

Example: bookingReference=h712345-yhfb-789746
agentId Required

Your personal agent identifier generated by Slice Pay.

โš ๏ธ Security Notice

Anyone with this key can generate payment links on your behalf. Treat it as a secret key and never expose it in client-side code.

Example: agentId=agent-123
bookingNotificationUrl Optional

Upon each successful deposit, this URL will be called by our systems via webhook.

URL Validation Criteria:

  • The URL MUST be valid
  • The URL MUST start with https://
  • The domain MUST be previously authorized for your agent
  • The URL MUST have NO querystring parameters

Webhook Request Details:

We'll perform a POST request with these headers:

  • Content-Type: application/x-www-form-urlencoded
  • Accept: text/html
  • X-Request-ID: [unique-id] - Use for deduplication

Webhook Parameters:

  • agentId - The original agentId that created the link
  • bookingReference - The original bookingReference this payment is related to
  • salePrice - The original salePrice in cents sent through Create Link API
  • currency - The original currency sent through Create Link API
  • Example: bookingReference=12345&agentId=agent-123&salePrice=1000&currency=AUD
Example: https://agent-website.com/callback

Successful Response #

โœ… HTTP 200 OK - Success Response

When successful, the API returns HTML containing a payment link that you can parse and use to redirect your customer.

HTML Response Body
<html>
    <a name="payment-link" href="[dynamically generated payment link]">
        Pay using instalments
    </a>
    <time class="sg-payment-link-expiry-date" datetime="2024-12-31T23:59:59Z"></time>
</html>

๐Ÿ’ก Implementation Tip

Use a DOM parser to extract the href attribute from the anchor tag with name="payment-link". The expiry date can be found in the datetime attribute of the time element.

More Implementation Examples #

Here are comprehensive examples showing how to integrate with the Create Payment Link API in different environments.

JavaScript Successful Response Handling (ES6) #

JavaScript Success Handling

const parse = html => new JSDOM(html).window.document;

// Make request
const url = 'https://api.staging.slicepay.travel/api/create-link';
const response = await fetch(url, {
    method: 'POST',
    headers: {
        'Accept': 'text/html',
        'Content-Type': 'application/x-www-form-urlencoded'
    },
        body: new URLSearchParams({
            salePrice: '100000',
            currency: 'AUD',
            departureDate: '2030-10-01',
            bookingReference: 'ABC123',
            agentId: 'agent-bypass-5kyp4y'
        }).toString()
});

// Response Handling
const responseBody = await response.text();
const paymentLinkHref = parse(responseBody).querySelector('a[name="payment-link"]')?.href;
const paymentLinkText = parse(responseBody).querySelector('a[name="payment-link"]')?.textContent;
const paymentLinkExpiryDate = parse(responseBody).querySelector('.sg-payment-link-expiry-date')?.getAttribute('datetime');
if (paymentLinkHref && response.status === 200) {
    const paymentLink = {
        href: paymentLinkHref,
        text: (paymentLinkText || '').trim(),
        expiryDate: paymentLinkExpiryDate
    };
    use(paymentLink); // Payment link is available, use it as a payment option to customer
} else {
    throw new Error(`Unexpected response: ${response.status} ${responseBody}`);
}
                

JavaScript Error Handling (ES6) #

JavaScript Error Handling
const parse = html => new JSDOM(html).window.document;

// Make request
const url = 'https://api.staging.slicepay.travel/api/create-link';
const response = await fetch(url, {
    method: 'POST',
    headers: {
        'Accept': 'text/html',
        'Content-Type': 'application/x-www-form-urlencoded'
    },
        body: new URLSearchParams({
            //salePrice: '100000', // <-- Missing required field "salePrice"
            currency: 'AUD',
            departureDate: '2030-10-01',
            bookingReference: 'ABC123',
            agentId: 'agent-bypass-5kyp4y'
        }).toString()
});

// Response Handling - See Problem Responses section for details
const responseBody = await response.text();
const problemTitle = parse(responseBody).querySelector('.sg-problem .sg-problem-title')?.textContent;
const problemDescription = parse(responseBody).querySelector('.sg-problem .sg-problem-description')?.textContent;
if (problemTitle && response.status === 400) {
    const problemDetails = {
        problemTitle: problemTitle.trim(),
        problemDescription: (problemDescription || '').trim()
    };
    handleError(problemDetails);
} else {
    throw new Error(`Unexpected response: ${response.status} ${responseBody}`);
}

โ„น๏ธ Complete Error Handling

For comprehensive error handling patterns and status codes, see the Problem Responses section.

Browser Form Example #

Save this code in a .html file and open with the browser.

HTML Form Example

<!doctype html>
<html lang="">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title></title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/html5-boilerplate@5.3.0/dist/css/main.css">
        <style>
        * {
            font-family: Arial, sans-serif;
        }
        /*
            1. Remove shadow border for Samsung devices
            2. Remove default border width and style for Chrome on Windows
            3. Safari on iPhone requires border set
        */
        .sp-btn {
            position: relative;
            padding: 15px 15px 15px 15px;
            color: #000;
            margin: -1px auto;
            display: block;
            width: 100%;
            text-align: left;
            box-shadow: 3px 3px 3px 0px rgb(0 0 0 / 10%);
            -webkit-appearance: none;
            font-size: 1em;
            border-radius: 10px;
            text-align: center;
            font-weight: normal;
            border-width: 1px; /* 2 */
            border-style: solid; /* 2 */
            border-color: #000; /* 3 */
            background-color: #FFF; /* 1 */
        }
        </style>
        <meta name="theme-color" content="#fafafa">
    </head>
    <body>
        <div style="margin: auto auto; display: flex; justify-content: center;">
            <div style="max-width: 400px; margin: auto auto;">
                <form name="create-payment-link" method="POST" action="https://api.staging.slicepay.travel/api/create-link">
                <div>
                    Sale Price: <input type="text" name="salePrice" inputmode="numeric" required value="100000">
                </div>
                <div>
                    Currency: <input type="text" name="currency" required value="AUD">
                </div>
                <div>
                    Departure: <input type="date" name="departureDate" required value="2030-10-01">
                </div>
                <div>
                    Booking Reference: <input type="text" name="bookingReference" required value="ABC123">
                </div>
                <div>
                    AgentId: <input type="text" name="agentId" value="agent-bypass-5kyp4y" required>
                </div>
                <button type="submit" style="margin-top: 10px;" class="sp-btn">Generate Payment Link</button>
                </form>
            </div>
        </div>
    </body>
</html>
                

Embedded Flow #

Create an embedded payment experience that allows customers to select their payment plan directly on your website. This provides a seamless, branded experience while keeping customers on your site.

๐Ÿ’ก Enhanced Experience

The embedded flow provides the best user experience by allowing customers to see and select their preferred payment plan without leaving your website. Perfect for maintaining brand consistency and improving conversion rates. You can even customize the background color to match your site's theme and ensure consistent appearance across different device themes.

โš ๏ธ Important Note

The embedded flow requires webhook integration to handle payment notifications. Make sure your bookingNotificationUrl is properly configured and can handle POST requests from our system.

Quick Links

Need the simpler integration? Check out the Regular Flow which redirects customers to our hosted payment page.

API Request #

cURL Example #

cURL Request
curl --location --request POST 'https://api.staging.slicepay.travel/api/create-link/embedded' \
--header 'Accept: text/html' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'salePrice=1000' \
--data 'currency=AUD' \
--data 'departureDate=2030-10-01' \
--data 'agentId=agent-bypass-5kyp4y' \
--data 'bookingReference=ABC123' \
--data 'bookingNotificationUrl=https://example.com/test-callback'

Raw HTTP Example #

HTTP Request
POST /api/create-link/embedded HTTP/1.1
Host: api.staging.slicepay.travel
Accept: text/html
Content-Type: application/x-www-form-urlencoded
Content-Length: 103

salePrice=1000¤cy=AUD&departureDate=2030-10-01&agentId=agent-bypass-5kyp4y&bookingReference=ABC123&bookingNotificationUrl=https://example.com/test-callback

Required Headers #

Accept: text/html Required

Accept headers indicate to the server the media types the client accepts as a response. We require the specific text/html value. Catch-all values such as */* are NOT supported.

Content-Type: application/x-www-form-urlencoded Required

Indicates the request fields need to be in the format name1=value&name2=value&name3=value. This is the same media type used by HTML Form Submission requests.

Request Fields #

salePrice Required

Number in cents representing the total amount of the sale.

Precision of 2 digits by default: 10000 โ†’ 100.00 โ†’ $100.00

Example: salePrice=256058 โ†’ $2560.58
currency Required

A 3-letter currency code representing the currency.

Follows ISO 4217 currency codes .

Example: currency=AUD
departureDate Required

The date when the flight departs.

An ISO 8601 date format representing the departure date.

Example: departureDate=2024-03-12
bookingReference Required

The booking reference used to identify the booking related to this payment plan link.

SHOULD be a unique ID per booking within your agency. We'll use this to query you for more information about the booking.

You can generate multiple payment plan links for the same bookingReference.

Limited to 20 characters long using UTF-8 encoding.

Example: bookingReference=h712345-yhfb-789746
agentId Required

Your personal agent identifier generated by Slice Pay.

โš ๏ธ Security Notice

Anyone with this key can generate payment links on your behalf. Treat it as a secret key and never expose it in client-side code.

Example: agentId=agent-123
bookingNotificationUrl Required

Upon each successful deposit, this URL will be called by our systems via webhook.

URL Validation Criteria:

  • The URL MUST be valid
  • The URL MUST start with https://
  • The domain MUST be previously authorized for your agent
  • The URL MUST have NO querystring parameters

Webhook Request Details:

We'll perform a POST request with these headers:

  • Content-Type: application/x-www-form-urlencoded
  • Accept: text/html
  • X-Request-ID: [unique-id] - Use for deduplication

Webhook Parameters:

  • agentId - The original agentId that created the link
  • bookingReference - The original bookingReference this payment is related to
  • salePrice - The original salePrice in cents sent through Create Link API
  • currency - The original currency sent through Create Link API
  • Example: bookingReference=12345&agentId=agent-123&salePrice=1000&currency=AUD
Example: https://agent-website.com/callback
redirectUrlSucceeded Optional

Upon each successful deposit, we'll instruct the User Agent to perform a GET request on redirectUrlSucceeded.

URL Validation Criteria:

  • The URL MUST be valid
  • The URL MUST start with https://
  • The domain MUST be previously authorized for your agent
Examples: https://agent-website.com/done, https://agent-website.com/done?exampleSessionId={example-session-id}, https://agent-website.com/done/{example-session-id}

Successful Response #

โœ… HTTP 200 OK - Success Response

When successful, the API returns HTML containing a payment link that you can parse and use to redirect your customer.

HTML Response Body
<html>
    <a name="payment-link" href="[dynamically generated payment link]">
        Pay using instalments
    </a>
    <time class="sg-payment-link-expiry-date" datetime="2024-12-31T23:59:59Z"></time>
</html>

๐Ÿ’ก Implementation Tip

Use a DOM parser to extract the href attribute from the anchor tag with name="payment-link". The expiry date can be found in the datetime attribute of the time element.

More Implementation Examples #

Here are comprehensive examples showing how to integrate with the Create Payment Link API in different environments.

JavaScript Successful Response Handling (ES6) #

JavaScript Success Handling

const parse = html => new JSDOM(html).window.document;

// Make request
const url = 'https://api.staging.slicepay.travel/api/create-link';
const response = await fetch(url, {
    method: 'POST',
    headers: {
        'Accept': 'text/html',
        'Content-Type': 'application/x-www-form-urlencoded'
    },
        body: new URLSearchParams({
            salePrice: '100000',
            currency: 'AUD',
            departureDate: '2030-10-01',
            bookingReference: 'ABC123',
            agentId: 'agent-bypass-5kyp4y'
        }).toString()
});

// Response Handling
const responseBody = await response.text();
const paymentLinkHref = parse(responseBody).querySelector('a[name="payment-link"]')?.href;
const paymentLinkText = parse(responseBody).querySelector('a[name="payment-link"]')?.textContent;
const paymentLinkExpiryDate = parse(responseBody).querySelector('.sg-payment-link-expiry-date')?.getAttribute('datetime');
if (paymentLinkHref && response.status === 200) {
    const paymentLink = {
        href: paymentLinkHref,
        text: (paymentLinkText || '').trim(),
        expiryDate: paymentLinkExpiryDate
    };
    use(paymentLink); // Payment link is available, use it as a payment option to customer
} else {
    throw new Error(`Unexpected response: ${response.status} ${responseBody}`);
}
                

JavaScript Error Handling (ES6) #

JavaScript Error Handling
const parse = html => new JSDOM(html).window.document;

// Make request
const url = 'https://api.staging.slicepay.travel/api/create-link';
const response = await fetch(url, {
    method: 'POST',
    headers: {
        'Accept': 'text/html',
        'Content-Type': 'application/x-www-form-urlencoded'
    },
        body: new URLSearchParams({
            //salePrice: '100000', // <-- Missing required field "salePrice"
            currency: 'AUD',
            departureDate: '2030-10-01',
            bookingReference: 'ABC123',
            agentId: 'agent-bypass-5kyp4y'
        }).toString()
});

// Response Handling - See Problem Responses section for details
const responseBody = await response.text();
const problemTitle = parse(responseBody).querySelector('.sg-problem .sg-problem-title')?.textContent;
const problemDescription = parse(responseBody).querySelector('.sg-problem .sg-problem-description')?.textContent;
if (problemTitle && response.status === 400) {
    const problemDetails = {
        problemTitle: problemTitle.trim(),
        problemDescription: (problemDescription || '').trim()
    };
    handleError(problemDetails);
} else {
    throw new Error(`Unexpected response: ${response.status} ${responseBody}`);
}

โ„น๏ธ Complete Error Handling

For comprehensive error handling patterns and status codes, see the Problem Responses section.

Browser Form Example #

Save this code in a .html file and open with the browser.

HTML Form Example

<!doctype html>
<html lang="">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title></title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/html5-boilerplate@5.3.0/dist/css/main.css">
        <style>
        * {
            font-family: Arial, sans-serif;
        }
        /*
            1. Remove shadow border for Samsung devices
            2. Remove default border width and style for Chrome on Windows
            3. Safari on iPhone requires border set
        */
        .sp-btn {
            position: relative;
            padding: 15px 15px 15px 15px;
            color: #000;
            margin: -1px auto;
            display: block;
            width: 100%;
            text-align: left;
            box-shadow: 3px 3px 3px 0px rgb(0 0 0 / 10%);
            -webkit-appearance: none;
            font-size: 1em;
            border-radius: 10px;
            text-align: center;
            font-weight: normal;
            border-width: 1px; /* 2 */
            border-style: solid; /* 2 */
            border-color: #000; /* 3 */
            background-color: #FFF; /* 1 */
        }
        </style>
        <meta name="theme-color" content="#fafafa">
    </head>
    <body>
        <div style="margin: auto auto; display: flex; justify-content: center;">
            <div style="max-width: 400px; margin: auto auto;">
                <form name="create-payment-link" method="POST" action="https://api.staging.slicepay.travel/api/create-link">
                <div>
                    Sale Price: <input type="text" name="salePrice" inputmode="numeric" required value="100000">
                </div>
                <div>
                    Currency: <input type="text" name="currency" required value="AUD">
                </div>
                <div>
                    Departure: <input type="date" name="departureDate" required value="2030-10-01">
                </div>
                <div>
                    Booking Reference: <input type="text" name="bookingReference" required value="ABC123">
                </div>
                <div>
                    AgentId: <input type="text" name="agentId" value="agent-bypass-5kyp4y" required>
                </div>
                <button type="submit" style="margin-top: 10px;" class="sp-btn">Generate Payment Link</button>
                </form>
            </div>
        </div>
    </body>
</html>