# Get started

PaySG is a free-to-use platform built for government agencies to collect online payments. It enables agencies to collect payments through our no-code tools and/or by integrating our API

{% hint style="danger" %}
As of 25 June 2025,\
\
PaySG will not be onboarding new users until further notice. Users may onboard to our dashboard independently using the resources in the [Payment services section](/start-using-the-dashboard/payment-services) but onboarding support will not be available. Use cases that require API keys and webhooks will not be able to onboard during this period. \
\
We remain fully operational for existing users and will continue to assist with critical technical issues, such as payment failures or unexpected system behaviours on PaySG’s end.
{% endhint %}

[**Learn more about what PaySG offers**](#user-content-fn-1)[^1]

1. Read through our [resource guide](/overview/resource-guides). You can also log in to our [test environment (staging.pay.gov.sg)](https://staging.pay.gov.sg) to explore our features.
2. Refer to our [FAQs](/faq/access) for common queries on setting up, usage and troubleshooting.

**Setup a collection workflow**

1. Once you've confirmed that PaySG fits your payment collection workflow, begin the [payment method onboarding ](/overview/stripe-onboarding)process with Stripe, our underlying payment processor.
2. Test your end-to-end payment workflow in our [test environment](https://staging.pay.gov.sg) to ensure your set-up is working as expected. Verify that you've selected the correct settings and input the correct details as these can't be edited or deleted once created.&#x20;
3. Once you've verified that your set-up is working, you're ready to start collecting payments in our [live environment](https://pay.gov.sg).

**Estimated timeline**

{% hint style="warning" %}
The stakeholders and durations listed in the tables are **not prescriptive**. Stakeholders and durations differ between teams.
{% endhint %}

<table><thead><tr><th width="155">Phase</th><th width="160">Duration</th><th>Task</th><th>Stakeholder</th></tr></thead><tbody><tr><td>Budget approval</td><td>Based on your team</td><td>Seek clearance from your team/department head to budget for the transaction fees incurred by Stripe if necessary</td><td><ol><li>Your team</li><li>Team/department head who can approve budget requests</li></ol></td></tr><tr><td>Stripe set up</td><td>Based on your team</td><td>Follow the steps in our <a href="/pages/n6YnXMOkk4BYGFbx54A2">Stripe onboarding guide</a></td><td><ol><li>Your team</li><li>Procurement/finance team</li></ol></td></tr><tr><td>Testing in PaySG's staging environment</td><td>2-4 weeks, based on your implementation team</td><td>Complete testing in our staging environment to ensure that details and payment flows are working as expected</td><td>For dashboard-only users: Your team<br><br>For API users:<br>Your technical team/vendor</td></tr><tr><td>Testing in PaySG's production environment</td><td>2-4 weeks, based on your implementation team</td><td>Complete testing in our staging environment to ensure that details and payment flows are working as expected</td><td>For dashboard-only users: Your team<br><br>For API users:<br>Your technical team/vendor</td></tr><tr><td>Go live</td><td>Based on your team</td><td></td><td>For dashboard-only users: Your team<br><br>For API users:<br>Your technical team/vendor</td></tr></tbody></table>

[^1]:


# Resource guides

Explore our resource guides, tailored to the key stakeholder groups that use PaySG.

* [**Business users**](/overview/resource-guides/for-business-users)**:** Evaluate PaySG for your team's use cases. The resources include details on how to incorporate PaySG for various workflows and offers guidance on project planning and implementation.
* [**Finance users**](/overview/resource-guides/for-finance-teams)**:** Discover how PaySG supports finance operations, including reporting, reconciliation, payments, refunds, and access controls features.
* [**Technical users**](/overview/resource-guides/for-integration-teams)**:** Explore our APIs and technical documentation to understand how PaySG can be integrated with your agency's e-services/websites and systems.


# For business users

## Introduction to PaySG

* [Possible use cases with PaySG](https://guide.pay.gov.sg/overview/use-cases)
* [Payments ](/faq/payments)FAQ
* [Timeline ](https://guide.pay.gov.sg/faq/timeline)FAQ
* [Costs](https://guide.pay.gov.sg/faq/costs) FAQ
* [Refunds](https://guide.pay.gov.sg/faq/refunds) FAQ
* [Downtime and maintenance](https://guide.pay.gov.sg/faq/downtime-and-maintenance) FAQ

## Collecting payments and processing refunds with PaySG

* [Payment method onboarding](/overview/stripe-onboarding)
* [Payment service creation](https://guide.pay.gov.sg/start-using-the-dashboard/payment-services)
* [Payment link creation](https://guide.pay.gov.sg/start-using-the-dashboard/payment-links)
* [Processing refunds on PaySG](https://guide.pay.gov.sg/start-using-the-dashboard/payments-and-refunds/refunds)


# For finance teams

## Collecting payments and processing refunds with PaySG

* [Payment method onboarding](/overview/stripe-onboarding)
* [Payment service creation](https://guide.pay.gov.sg/start-using-the-dashboard/payment-services)
* [Payment link creation](https://guide.pay.gov.sg/start-using-the-dashboard/payment-links)
* [Processing refunds on PaySG](https://guide.pay.gov.sg/start-using-the-dashboard/payments-and-refunds/refunds)

## Viewing payment information on PaySG

* [Using PaySG’s dashboard](https://guide.pay.gov.sg/start-using-the-dashboard/payments-and-refunds/dashboard)
* [PaySG’s reports](https://guide.pay.gov.sg/start-using-the-dashboard/reports)

## FAQs

* [Timeline](/faq/timeline)
* [Payments](https://guide.pay.gov.sg/faq/payments)
* [Refunds](https://guide.pay.gov.sg/faq/refunds)
* [Stripe](https://guide.pay.gov.sg/faq/stripe)


# For integration teams

This page is for technical users who are looking to integrate with PaySG

## Overview

* [Integration overview](https://guide.pay.gov.sg/start-an-api-integration/get-started)
* [Integrated payment flow](https://guide.pay.gov.sg/start-an-api-integration/integrating-with-your-e-services)

## Resources

* [Endpoints](https://guide.pay.gov.sg/start-an-api-integration/endpoints)
* [Payments](https://guide.pay.gov.sg/api-resources/payments)
* [Refunds](/api-resources/payments/refund-a-payment)
* [Events](https://guide.pay.gov.sg/api-resources/events)
* [Webhooks](https://guide.pay.gov.sg/webhooks/set-up)

## Troubleshooting

* [Errors](https://guide.pay.gov.sg/start-an-api-integration/errors)
* [FAQs](https://guide.pay.gov.sg/faq/integrating-with-paysg)

## Checklists

* [Go-live](https://guide.pay.gov.sg/start-an-api-integration/go-live-checklist)


# Stripe onboarding

All payments collected using PaySG are facilitated by [Stripe](https://stripe.com/en-sg). You must create a Stripe account to use PaySG.

![PaySG / Stripe payment flow](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuqMHPbRxvRp3K0CMQMjE%2Fuploads%2FYOzlMlo5qn2lpMDVdf67%2FScreenshot%202024-08-19%20at%2010.36.37%E2%80%AFPM.png?alt=media\&token=e7663cd0-f5f0-42c0-bb80-071f7239a7a0)

**Payment collection flow**

1. An agency user [creates a payment link](/start-using-the-dashboard/one-time-payment-links/single-link-creation) on our dashboard or via API. The payer accesses the payment link and inputs their details directly on our [payment page](/start-using-the-dashboard/one-time-payment-links/payment-link-page).
2. Stripe processes their payment details and facilitates the transaction.
3. Stripe deposits the payout into your receiving bank account.

## Stripe onboarding

### Before account creation

**Expected duration:** Dependent on your team's approval process, if any

1. Check with your finance team if your agency has an existing Stripe account that can be used. If not, identify a POC to own and create a Stripe account.
2. If necessary, get approval from the relevant budget head to account for Stripe's transaction fees under bulk tender GVT (T) 24010.

### Account creation

**Expected duration:** <1 day

1. Use an official email address to register for a Stripe account at <https://dashboard.stripe.com/register>.
2. Follow the step-by-step guided onboarding process.
3. The administrator of the Stripe account has to verify their identity through Singpass

{% hint style="success" %}
Once your account has been created, you may proceed to test out our platform at [staging.pay.gov.sg](https://staging.pay.gov.sg). The account verification and price application steps below can be done concurrently, in preparation for the collection of real payments.
{% endhint %}

### Price application

**Expected duration:** <2 weeks

For government users:

1. Issue a GeBiz PO (WOG bulk tender GVT (T) 24010) to Stripe.&#x20;
2. Stripe will respond with a fee schedule to be signed through Docusign.
3. On receiving the fee schedule, Stripe will apply the bulk tender rates to your account.

For healthcare clusters:

* The use of Stripe for PaySG payments falls within the parameters of MOM Circular No. 28/2022.
* Contact <govsg@stripe.com> directly.

### Representative authority verification

**Expected duration:** <2 weeks

An authorized senior representative listed in the SGDI should send Stripe (<sggovloa@stripe.com>) a [Letter of Authorization](https://file.go.gov.sg/paysg-stripe-poa.pdf). Please refer to [this page](https://support.stripe.com/questions/representative-authority-verification) for more details.

### After price application

**Expected duration:** For dashboard users: instant. For users integrating with PaySG: dependent on your technical team's timeline.

* Dashboard-only users: Start collecting payments instantly.
* Users with PaySG API integration: Start collecting payments once your team/vendor has completed integration


# Live use cases

The PaySG team has collaborated with the following agencies to offer PaySG's services to their payers.&#x20;

## API integration

* **Customs Goods Declaration Portal:** Payment of duty and/or GST.

<figure><img src="/files/NMvhbaxO0nWoXpuM8ptU" alt="" width="563"><figcaption><p>Customs declaration portal</p></figcaption></figure>

* **EMA Singapore International Energy Week (SIEW) 2024:** Payment of registration fees

<figure><img src="/files/gHy2lSuHzbFN5wnnXy13" alt="" width="563"><figcaption><p>EMA SIEW registration home page</p></figcaption></figure>

## Dashboard only (no-code)

* **MOM Migrant Worker Onboarding Centre (MWOC):** Payment for onboarding programme

<figure><img src="/files/dYGhmc1ZJgYtf5GQtht3" alt="" width="375"><figcaption><p>MOM MWOC payment instructions</p></figcaption></figure>

* **MUIS:** Payment of Halal certification fees.


# Usage overview

This page includes details of how PaySG can be incorporated into your agency's use cases.

<table><thead><tr><th width="160">Use case</th><th width="122">Method</th><th width="82">Integration required?</th><th>Workflow</th><th>Getting started</th></tr></thead><tbody><tr><td>Integrate PaySG with your licensing portal to enable users to make payments for license applications</td><td>Integration with e-services</td><td>Yes</td><td><p></p><ol><li>Payer accesses the licensing portal and inputs their details.</li><li>The licensing portal’s backend system calls our API to create a payment link.</li><li>Your portal redirects payer to PaySG’s payment page.</li><li>Payer completes payment and PaySG redirects them back to a return URL of your choice.</li></ol></td><td><ol><li>Read through our guide, specifically:</li></ol><p>- <a href="https://guide.pay.gov.sg/overview/get-started">Getting started</a> </p><p>- <a href="https://guide.pay.gov.sg/faq/timeline">Implementation timeline</a> </p><p>- <a href="https://guide.pay.gov.sg/start-an-api-integration/integrating-with-your-e-services">Integrating with your e-services</a></p><ol start="2"><li>Test out our services at <a href="http://staging.pay.gov.sg/">staging.pay.gov.sg</a> to assess if PaySG is suitable for your use case.</li></ol></td></tr><tr><td>Collecting money from an individual</td><td>Single adhoc</td><td>No</td><td><ol><li>Your team <a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-services">creates a payment service</a> on PaySG. </li><li>Your team <a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-links">creates a payment link</a> and inputs the payer’s details. </li><li><a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-links/send-payment-links">Send the payment link</a> to the payer via email on PaySG, or send them a PaySG QR code. </li><li>After successful payment, the payer receives a<a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-links/payment-confirmation-email"> receipt through email.</a></li></ol></td><td><ol><li>Read through our <a href="https://guide.pay.gov.sg/start-using-the-dashboard/">guide</a> on using the PaySG dashboard. <br></li><li>Decide which <a href="https://guide.pay.gov.sg/overview/payment-onboarding">payment options</a> you want to offer. <br></li><li>Test out our services at <a href="http://staging.pay.gov.sg/">staging.pay.gov.sg</a> to assess if PaySG is suitable for your use case.</li></ol></td></tr><tr><td>Collecting money from groups of people</td><td>Bulk adhoc</td><td>No</td><td><ol><li>Your team <a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-services">creates a payment service</a> on PaySG. </li><li>Your team <a href="https://go.gov.sg/paysg-csv-template">creates a csv file</a> that includes the payers’ contact details and information. </li><li>Your team uploads the csv file to <a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-links/bulk-link-creation">bulk-create payment links.</a> </li></ol><p></p><ol start="4"><li>Your team <a href="https://app.gitbook.com/o/AdD4O4aCdhHjPkGhKYtO/s/uqMHPbRxvRp3K0CMQMjE/start-using-the-dashboard/payment-links/send-payment-links">sends out the payment links</a> via individual or bulk email. </li></ol><p></p><ol start="5"><li>After successful payment, the payer receives a<a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-links/payment-confirmation-email"> receipt through email.</a></li></ol></td><td><ol><li>Read through our <a href="https://guide.pay.gov.sg/start-using-the-dashboard/">guide</a> on using the PaySG dashboard. </li><li>Decide which <a href="https://guide.pay.gov.sg/overview/payment-onboarding">payment options</a> you want to offer. </li><li>Test out our services at <a href="http://staging.pay.gov.sg/">staging.pay.gov.sg</a> to assess if PaySG is suitable for your use case.</li></ol></td></tr><tr><td>Automated payments workflow for fine collections</td><td>Integration with <a href="https://form.gov.sg">FormSG</a> via <a href="https://plumber.gov.sg">Plumber</a></td><td>No</td><td><p>Set up: </p><ol><li>Your team creates a <a href="http://form.gov.sg/">FormSG form</a>, <a href="http://pay.gov.sg/">PaySG payment service</a> and <a href="http://plumber.gov.sg/">Plumber pipe.</a> </li><li>Your team connects the FormSG form and PaySG payment service on Plumber. </li><li>After successfully connecting the form and payment service, Plumber facilitates the creation of a payment service after a form input.</li></ol><p></p><p>Payment flow: </p><ol><li>Payer inputs details on a FormSG form. </li><li>Using payer's details, a payment link or fine letter is automatically created and sent to the payer’s email. </li><li>After successful payment, the payer receives a<a href="https://guide.pay.gov.sg/start-using-the-dashboard/payment-links/payment-confirmation-email"> receipt through email.</a></li></ol></td><td><ol><li>For payment generation, test out the flow at <a href="https://go.gov.sg/paysg-plumber-demo">go.gov.sg/paysg-plumber-demo</a>. For payment and fine letter generation, test out the flow at <a href="https://go.gov.sg/paysg-fine-demo">go.gov.sg/paysg-fine-demo</a>.</li><li>Refer to our <a href="https://guide.pay.gov.sg/overview/use-cases/paysg-and-plumber-guide">guide</a> for more information on setting up the pipe for your own workflow.</li></ol></td></tr></tbody></table>


# Payment services

This guide will walk you through the process of creating a payment service in PaySG. Once you've created a payment service, you can start creating payment links to collect payments.

{% hint style="danger" %}
As of 25 June 2025, PaySG will not be onboarding new users until further notice. Users may onboard to our dashboard independently using the resources listed below, but onboarding support will not be available. Use cases that require API keys and webhooks will not be able to onboard during this period.&#x20;
{% endhint %}

{% hint style="info" %}
The following sections are applicable to users who would like to set up independently. Following the resources in these sections will enable you to collect and refund one-time payments and download accompanying reports for reconciliation and tracking.

* [Payment services](/start-using-the-dashboard/payment-services)
* [Collaborators and access control](/start-using-the-dashboard/collaborators-and-access-control)
* [One-time payment links](/start-using-the-dashboard/one-time-payment-links)
* [Payments and refunds](/start-using-the-dashboard/payments-and-refunds)
* [Payouts](/start-using-the-dashboard/payouts)
* [Reports](/start-using-the-dashboard/reports)
* [FAQs](/faq/access)[<br>](/start-using-the-dashboard/reports)

The following sections are not applicable and cannot be set up independently as API keys are not being issued:

* Subscriptions
* Payment workflows with Plumber
* Payment forms
  {% endhint %}

## Access to PaySG

Use a valid gov.sg email to log in without any prior set up, there is no need to create an account to use PaySG. Agencies should contact PaySG to request for vendor's non-gov.sg email addresses to be whitelisted.

The **staging environment** (<https://staging.pay.gov.sg>) allows you to test out your payment flow without real money. You should always test out your payment flow on our staging environment before accessing our production environment.

The **production environment** (<https://pay.gov.sg>) will transact with real money, so you should be sure of your setup before using this platform.

Once you enter your email and click sign in, an OTP (One-Time Password) will be sent to your email for verification. OTPs sent to GSIB users might be delayed in times of higher load.&#x20;

## Creating payment services

### Interactive demo

For users who will require a finance representative to connect a Stripe account on your behalf after payment service creation, please refer to the [next section](#connecting-a-stripe-account-after-payment-service-creation).

{% hint style="info" %}
The "Email greeting" field is not applicable to [payment forms](/start-using-the-dashboard/payment-forms) users. You may use a placeholder to fill in the field.
{% endhint %}

{% embed url="<https://app.arcade.software/share/MjPUeogET3HFRtNjv16C>" %}

### Steps

1. [Creating a payment service](#step-2-creating-a-payment-service)
2. [Providing payment service details](#step-3-providing-payment-service-details)
3. [Review and connect with Stripe](#step-4-review-and-connect-with-stripe)
4. [Logging in to Stripe](#step-5-logging-into-stripe)
5. [Complete your payment service creation](#step-6-complete-your-payment-service-creation)

#### **Step 1: Creating a payment service**

On the dashboard, click on "Create Payment Service".

#### **Step 2: Providing payment service details**

Fill in the required information for your payment service. These fields are not customisable.

* **Payment Service Name:** Choose a name that clearly represents the service you are offering.
* **Email Greeting:** Customise the email greeting that users will receive when making payments. This email greeting will be shown when you send PaySG's payment emails from our dashboard. If you won't be using this feature, the email greeting will not be reflected elsewhere.
* **Custom Logo:** Optionally, upload a logo that represents your agency or the specific service.&#x20;
* **Agency Name, Address, and Contact**: Provide the relevant contact information for your agency.
* **Support Channels:** Specify the channels through which users can reach out for support, such as email or website.
* **GST Rate:** In light of recent GST changes and the government's efforts to cushion the impact of the GST increase, we support variable GST rates and an optional GST rebate.

Review and finalise the payment service details. **Once a payment service has been created, it cannot be edited or deleted.**

#### **Step 3: Review and connect with Stripe**

Click on the "Connect with Stripe to continue" button. You will be redirected to the Stripe login page.

For more information about connecting to Stripe, please refer to our section on [Stripe onboarding](/overview/stripe-onboarding).

#### **Step 4: Logging into Stripe**

Log into the Stripe account that you want to connect with PaySG. Enter your Stripe account credentials and follow the prompts to complete the connection process.

#### Step 5: Complete your payment service creation

Congratulations! You have successfully created a payment service in our staging environment. You can now proceed to create a payment service to collect real payments in our production environment ([pay.gov.sg](https://pay.gov.sg)).

To find out more about how you can add collaborators to your payment service, [refer to our section on adding collaborators.](/start-using-the-dashboard/collaborators-and-access-control)

## Connecting a Stripe account after payment service creation

For users who will require a finance representative to connect a Stripe account on your behalf after payment service creation, please follow the interactive demo below.

{% embed url="<https://app.arcade.software/share/uvgjfLeuoZEgl3mx4E5H>" %}


# Collaborators and access control

The collaborator feature in PaySG allows you to add colleagues to your payment service, enabling them to view and edit the service's settings and payment links.

## Interactive demo

Try out our interactive demo below to learn how to (1) add collaborators, (2) update permissions and (3) remove collaborators.

{% embed url="<https://app.arcade.software/share/dUUNFw6ITE0vWNGh4NfF>" %}

## Access control

PaySG offers the following permissions: Administrator, View, Billing, and Refund.

#### View permissions

By default, all collaborators will have View permissions.&#x20;

| Collaborators with View permissions can:                                | Collaborators with View permissions cannot:                                                                                       |
| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| <ul><li>View payment details</li><li>Download payment reports</li></ul> | <ul><li>Create, send or cancel payment links</li><li>Initiate refunds </li><li>View, add and remove other collaborators</li></ul> |

#### Administrator permissions

Collaborators with Administrator permissions can:

* View, add and remove other collaborators

**Billing permissions**

Collaborators with Billing permissions can:

* Create, send or cancel payment links
* Send payment reminders
* Cancel subscriptions

**Refund permissions**

Collaborators with Refund permissions can:

* Initiate refunds


# One-time payment links

Create payment links in your payment services to start collecting payments from MOPs.

## Creating payment links

To create individual payment links, [refer to our guide to single link creation](/start-using-the-dashboard/one-time-payment-links/single-link-creation).

To bulk create payment links, [refer to our bulk link creation guide](/start-using-the-dashboard/one-time-payment-links/bulk-link-creation).

## Sending payment links

To find out more about how you can send out payment links, [refer to the section on sending payment links.](#sending-payment-links)

## Receiving payment links and making payment

To find out more about what the payee receives, check out the following pages.

* Making payment on PaySG's payment page: [Payment page](/start-using-the-dashboard/one-time-payment-links/payment-link-page)
* Receiving payment receipt: [Confirmation email](/start-using-the-dashboard/one-time-payment-links/payment-receipt-email)&#x20;


# Single link creation

Single link creation is suitable for ad-hoc payments or scenarios where you need to create individual payment links.

## Interactive demo

{% embed url="<https://app.arcade.software/share/4E5UfDYNvgEsQ0txgzoH>" %}

## Steps

{% hint style="warning" %}
The details included in the payment link will be reflected in the corresponding receipt/tax invoice.

Please refer to [IRAS' page](https://www.iras.gov.sg/taxes/goods-services-tax-\(gst\)/basics-of-gst/invoicing-price-display-and-record-keeping/invoicing-customers) for information required in a tax invoice. These fields are included on our payment link creation page but may be optional.&#x20;
{% endhint %}

1. Navigate to the payment link creation section, and select 'Create single link'.
2. Fill in the required information:
   1. Payment reference
   2. Payer name
   3. Amount
   4. About payment
3. The following fields are optional:
   1. Address
   2. Identifier
   3. Email: Include the payer's email address if you require a payment email to be automatically sent after payment.
   4. Due date: For display only. Payment links will not automatically be cancelled after the due date.
4. Optionally, you can include up to 10 additional rows of custom information. This allows you to provide context or attach relevant details related to the payment.
5. Review the entered information to ensure accuracy.
6. Click on the "Create" button to generate the payment link.

<figure><img src="/files/4FrgBTZns1EF2algt3C6" alt="" width="563"><figcaption></figcaption></figure>


# Bulk link creation

Bulk link creation is suitable when you need to create a large volume of payment links at once. It allows you to streamline the process and save time.

## Interactive demo

{% embed url="<https://app.arcade.software/share/g82yfXwLyn6fm5qWWD5H>" %}

## Steps

1. Visit <https://go.gov.sg/paysg-csv-template> to download a CSV template.
2. Fill in the CSV template with the required columns:
   1. Payment reference
   2. Payer name
   3. Amount
   4. About payment
3. The following fields are optional:
   1. Address
   2. Identifier
   3. Email: Include the payer's email address if you require a payment email to be automatically sent after payment.
   4. Due date: For display only. Payment links will **not** automatically be cancelled after the due date.
4. Save the file and upload it to the ‘Bulk create links’ section on the payment service page.
5. PaySG will perform basic checks on the CSV file to ensure its integrity and accuracy (**Note**: Refer to the [next section on ‘Data Verification for Bulk Upload’](#data-verification-for-bulk-uploads)).
   1. Any columns outside of the required fields will be added as custom information for each payment link.
   2. Any errors in the CSV file will be added and available for download. Please refer to the error message to correct the errors before re-uploading for verification.
6. Once the CSV file passes the verification checks, PaySG will create the payment links in bulk.

<figure><img src="/files/B8UeO9BeGQbkBWcwPi8I" alt=""><figcaption><p>Bulk creation CSV template</p></figcaption></figure>

### Data Verification for Bulk Uploads

The following are potential error reasons you may be prompted with; do ensure you verify the data accuracy, integrity and formats accordingly for a successful bulk upload:

* **Payment Reference**: In Microsoft Excel, numbers are limited to 11 digits of precision. If your 'Payment Reference' field is populated with a number of 12 digits or more, Excel automatically converts the data to scientific notation as a way to conform to that limit and it will be uploaded to PaySG in the same format (e.g. 1.04E+11). To prevent this, ensure that your cell is formatted as 'Text', or use a leading apostrophe (') before the data to ensure that Excel treats it as text, rather than a number.
* '**Payer Identifier** *must be less than 10 characters long*': If payment will be made by an individual citizen, enter NRIC. NRIC is alphanumeric and consists of nine letters/digits. If payment will be made by a company, enter UEN. Unique Entity Number (UEN) is a 9- or 10-digit identification number.
* '**Email** *must be a valid email*': The data verification process checks that the email domain is valid, e.g. <johndoe@domain.com.sg>.
* '**Amount** *must be at least 0.50. Amount must be less than 999,999.99. Must be a valid whole number or a number with 2 decimal places*': To prevent possible error(s), ensure that all amounts entered are displayed with two decimal places. To prevent, for example, "40.10" automatically converting to "40.1" by Excel, ensure that your cell is formatted as 'Text', or use a leading apostrophe (') before the data to ensure that Excel treats it as text, rather than a number.
* ’**Due Date** *must be a date string in the format DD-MMM-YYYY and must be between years 2021 and 2025., e.g. 01-Jan-2023*': To prevent possible error(s), ensure that your cell is formatted as 'Text', or use a leading apostrophe (') before the data to ensure that Excel treats it as text, rather than reformatting the date.


# Send payment links

Send payment links to payers collect fees, donations, or one-off payments—no ne

Once you've created a payment link, you'll need to select your preferred method to send it out to the recipients to make payment. By default, there is no automated sending of payment links.

PaySG allows you to send payment links via different methods:

1. [Send payment links via email](#send-payment-links-via-email)
2. [Send payment links via alternative methods](#send-payment-links-via-alternative-methods)
3. [Send all unsent payment links](#send-all-unsent-payment-links)

## Via email

<figure><img src="/files/JEfqFmlbLGp2ubQcHpEG" alt=""><figcaption></figcaption></figure>

1. Click on the "Send Link" button associated with the payment link.
2. PaySG will automatically send the payment link to the email address provided for the payer.
3. This email will contain all the necessary information for the payer to complete the payment. **The logo and support email are customised during the payment service creation stage. The other details, including the email body, are not customisable.**

<figure><img src="/files/0xCpEm7EnKEAVf5PH6Xw" alt="" width="375"><figcaption></figcaption></figure>

## Via alternative methods&#x20;

&#x20;If you prefer to use alternative methods, you can copy the payment link or save the QR code to include in a message or letter.

1. Locate the desired payment link in the PaySG admin dashboard.
2. Copy the payment link by selecting and copying the URL provided or save the QR code.
3. Paste the link or QR code into your preferred messaging or email platform for sending to the payers.

## Send all unsent payment links

In cases where multiple payment links need to be sent, PaySG simplifies the process with the "Send All Unsent" button. This feature enables officers to send payment links to all payers who have not yet received their payment links.

1. Click on "Actions", then locate and click the "Send All Unsent" button.
2. Clicking this button will trigger PaySG to automatically send the payment links to all payees who have not yet received them.

### Sending reminders

If you need to send a reminder email, you may do so once you've sent out an initial email via PaySG. **Reminders can only be sent once and must be done manually.**

1. Click "Send reminder" on the selected payment link.

<figure><img src="/files/3VfTD0HdVgjHfGdc0DDW" alt=""><figcaption></figcaption></figure>

The reminder email is identical to the [initial email](#send-payment-links-via-email), with the addition of the following text. **This text is not customisable.**

<figure><img src="/files/3lnCNWyC93rvf6ZO1Qrv" alt="" width="375"><figcaption></figcaption></figure>


# Payment link page

Payment page example

Payment pages are hosted on the pay.gov.sg domain and provide comprehensive information related to the payment, including a summary table with the purpose of the payment and GST breakdown. The fields and layout of the payment page cannot be customised.

## Before payment

Once payers are ready to proceed with the payment, they can click on the "Proceed" button on the payment page. Payers can select from payment modes that your agency chooses to offer through Stripe and pay with the mode of their choice. Payments should be tested on the staging environment using [dummy credit card numbers. ](https://stripe.com/docs/testing)

<figure><img src="/files/C1ZprNJ0OfxizcADuB43" alt="" width="375"><figcaption></figcaption></figure>

## Incorrect payment details

Payers will see the following message if incorrect card details are used.&#x20;

<figure><img src="/files/9xSM154esQVY2wcF77aZ" alt="" width="375"><figcaption></figcaption></figure>

## After payment

Upon successful payment, the payment link will automatically generate an IRAS-compliant tax invoice/receipt. This document serves as proof of payment and includes all the necessary information for record-keeping and compliance purposes. **Once payment is made, all input fields will be removed and duplicate payments will not be possible.**

<figure><img src="/files/oWORsO14u9Z1xDvgqsJo" alt="" width="375"><figcaption></figcaption></figure>


# Payment receipt email

Payment confirmation email example

If payers' emails were entered during payment link creation, an email confirmation will automatically be sent upon successful payment. These emails provide important information about the payment and include a convenient link back to the IRAS-compliant tax invoice/receipt.<br>

<figure><img src="/files/0xCpEm7EnKEAVf5PH6Xw" alt="" width="375"><figcaption></figcaption></figure>


# Subscriptions

Initiate month recurring payments, aka subscriptions

## User flow

1. The payer makes an initial payment via credit/debit card to start the subscription.
2. From that point on, the payer will be charged using the same credit/debit card details on the same date every month.
3. The subscription can be cancelled at any time after it is started. In such case, the payer will no longer be charged from that point onwards. A subscription may be cancelled in the following ways:
   1. By the payer, through the link in their email receipt.
   2. By the admin, from the dashboard.
   3. By PaySG automatically, if a monthly charge fails for any reason (e.g. the expiry date of the credit/debit card has passed).

### Do note the following

* You cannot collect both one-time payments and subscriptions using the same payment service. To collect subscriptions, you must create a new payment service.
* Currently, subscriptions can only be created via a payment forms flow.
  * After creating your subscription payment service, see [Payment forms](/start-using-the-dashboard/payment-forms) for more details on how to set this up.
* For subscriptions, the only supported payment method is Stripe.

You may try out a demo [here](https://go.gov.sg/paysg-subscriptions-demo).


# Set-up

To set up a payment service that collects subscriptions (recurring payments),  select the "Subscription" payment service type. Refer to our [payment service creation](/start-using-the-dashboard/one-time-payment-links/single-link-creation) for more details.

<figure><img src="/files/CJ2rzJhEYmFupMs3MW5K" alt="" width="375"><figcaption></figcaption></figure>

For users who require a **finance representative** to connect a Stripe account on your behalf after payment service creation, please follow the interactive demo below.

{% embed url="<https://app.arcade.software/share/uvgjfLeuoZEgl3mx4E5H>" %}


# View subscriptions

The **"Payments" section** of our dashboard allows you to view all payments in a payment service, regardless of subscription and payer.&#x20;

The **"Subscriptions" section** allows you to view subscriptions grouped by individual payers.

<figure><img src="/files/vOxmCfo1G7OKjfnyStnd" alt="" width="563"><figcaption></figcaption></figure>

To view all payments associated with a payer's subscription, click into the rows of the table.

<figure><img src="/files/cSx2NEKQa68GaHF5fJnD" alt="" width="563"><figcaption></figcaption></figure>

For your ease of accounting, it is helpful to note that the payment reference for each payment is the subscription reference and payment, suffixed by:

* "-0" for the initial payment, and
* "-1", "-2", "-3" and so on for subsequent payments, in incrementing order.&#x20;


# Manage subscriptions

## For admins

By clicking into a payer's subscription, you will be able to see all associated payments, including the payer details. You can cancel the subscription from the dashboard.

<figure><img src="/files/ngHmIklKvAgskamSa30q" alt=""><figcaption></figcaption></figure>

## For payers

Payers will receive an email receipt upon successful subscription. From the link included in their email receipt, payers should click on the "Manage Subscription" button. They will then be redirected to a subscription management page where they can see their payment amount per month, payment history, and also cancel their subscription.

<figure><img src="/files/y0Ss0xam8BPX9TgyNuBb" alt="" width="375"><figcaption></figcaption></figure>

<figure><img src="/files/Mrsymk9IoDuB1eRuiGmI" alt=""><figcaption></figcaption></figure>


# Payments and refunds


# Payment methods

Information about available payment methods and how to add new payment methods.

## Stripe payment methods

Through Stripe, PaySG supports credit/debit cards, PayNow and e-wallet payments. Refer to [Stripe's support guide](https://support.stripe.com/questions/activate-a-new-payment-method) to find out more about adding/editing offered payment methods.

**Credit/debit cards**

To enable selected card payments, you will need to do the following:

1. In your Stripe dashboard, go to "Settings"
2. (For staging/UAT only) Toggle on "Test mode"
3. Go to "Payments"
4. Turn on/off the desired payment method

**Apple/Google Pay**

To enable payments via Apple or Google Pay, you will need to do the following:

1. In your Stripe dashboard, go to "Settings"
2. (For staging/UAT only) Toggle on "Test mode"
3. Go to "Payments"
4. Go to "Payment method domains"
5. Add staging.pay.gov.sg (for staging/UAT) or pay.gov.sg (for production)
6. Inform the PaySG team so that the relevant payment methods can be activated


# Dashboard

The dashboard provides officers with real-time updates on payment and email delivery statuses, giving them a clear overview of the created payment links.&#x20;

* **Payment links overview**: The dashboard displays a list of all created payment links, offering key details such as the payment reference, name, and email associated with each link.
* **Side panel for detailed link information**: By clicking on a specific link in the dashboard, a side panel opens up. This includes information supplied by agencies, as well as the email, payment, and payout statuses.
* **Search feature:** Search for a specific payment link using its Payment Reference, Name or Email.

<figure><img src="/files/Tf3sMDRoRDt9LewrEkth" alt=""><figcaption></figcaption></figure>


# Refunds

### Initiating refunds

1. On the admin dashboard, select the relevant payment link and click "Refund". **Refunds are only valid for 90 days from the initial date of payment.** After 90 days, refunds must be handled manually off of PaySG.

<figure><img src="/files/CizepWxWEF3Pn9YvcZ8G" alt=""><figcaption></figcaption></figure>

### Entering refund amount(s)

&#x20;You may:

1. Issue a full refund by entering the full refundable amount.
2. Issue a partial refund by entering an amount within the remaining refundable amount. You may create multiple partial refunds within the remaining refundable amount.

<figure><img src="/files/WcO5NqpUfTblc68RZXMz" alt="" width="375"><figcaption></figcaption></figure>

### Viewing refund statuses

**For agencies**

Once the refund request has been successfully submitted, the payment status will be updated from "Paid" to "Refunded" (for fully refunded amounts) or "Partial Refunded" (for amounts lower than the remaining refundable amount).

**For payers**

Payers may return to the original payment page to view refund information.

<figure><img src="/files/JvrebNjYz1IIoPVkUNz8" alt="" width="375"><figcaption><p>Payment page after successful payment</p></figcaption></figure>

<figure><img src="/files/zVmLvy80s4M5UpTwJaVf" alt="" width="375"><figcaption><p>Payment page after refunds</p></figcaption></figure>


# Payouts

A payout is the transfer of funds from an agency's Stripe account to their receiving bank account

Payouts are sent out automatically on a daily basis by default. The frequency can be updated on [Stripe's dashboard](https://dashboard.stripe.com/settings/payouts) if needed. Payouts are typically received 3 business days after the initial payment. More information about Stripe's payouts can be found in [their guide.](https://stripe.com/docs/payouts)

<figure><img src="/files/2T8PmWwHNeHinb0UIYUP" alt=""><figcaption></figcaption></figure>

We generate a CSV report for each payout to your agency’s bank account, containing all the component transactions. You may refer to our section on [reports](/start-using-the-dashboard/reports) for more information.


# Reports

This page provides information about the various reports that can be downloaded on the PaySG dashboard.

PaySG provides our users with payment reports, generated on demand, and payout reports, generated for each payout deposited into your receiving bank account. **The report is not customisable.**

## On-demand payment reports

You can download a csv file of all payment links in a payment service. Select your payment service of choice and download the payments under "Actions".&#x20;

Try out our interactive demo below:

{% embed url="<https://app.arcade.software/share/qqQ8PVPMGDg5w4QEPaaM>" %}

<figure><img src="/files/7V0bKWvdUB4VdRiN63o9" alt=""><figcaption></figcaption></figure>

### Payment report fields

The following fields would have been **input during payment link creation.**

* Payment Reference: Reference ID of your choice that is input during the creation of payment links.&#x20;
* Name: Payer’s name.
* Address: Payer’s address.
* Identifier: Payer’s identifier of your agency’s choice (e.g. NRIC, passport number).
* Email: Payer’s email.
* Amount (SGD): Payment amount inclusive of GST.
* Due Date: Optional due date for display purposes only.
* About Payment: Payment description.
* (if applicable) Line items: Available via API only.
* (if applicable) Metadata: Each added metadata will be displayed in its own column.

The following fields are **based off of actions performed on the payment or payment link and are tracked by PaySG.**

* PaySG ID: Unique ID set by PaySG.
* Created by: Email of the individual who created the payment link.
* Payment Link URL: Link to the PaySG payment page.
* Payment Status: Payment status (Paid, Unpaid, Cancelled, Fully refunded, Partial refunded)
* Payout ID: Stripe payout ID. Also found in payout report.
* Email Status: Reflects status of payment email.
* Link sent on: Date when payment link was sent via email on PaySG dashboard.
* Created on: Date of payment link creation.
* Paid on: Date that payer successfully made payment.
* Paid Out on: Date of payout to your agency’s bank account.
* Refunded on: Date of refund(s) and refunded amount(s).

## Payout reports

PaySG generates a report for each payout received in your bank account. Select your payment service of choice and download the report under the "Reports" tab.&#x20;

Try out our interactive demo below:

{% embed url="<https://app.arcade.software/share/1fAwLRTDKJa8882FhR2R>" %}

<figure><img src="/files/BrGdwI9fqh45vA8b4kx1" alt=""><figcaption></figcaption></figure>

### Payout report fields

* payout\_id: ID of the payout credited to your agency's bank account
* payout\_date: Date that payout is credited to your agency’s bank account
* paysg\_id: Unique ID set by PaySG
* paysg\_payment\_service\_id: Payment service ID
* transaction\_ID: Transaction ID generated by Stripe or bank
* transaction\_type: Transaction type (Charge)
* transaction\_timestamp: Timestamp of when payment is made
* transaction\_amt\_in\_dollars: Amount before deduction of transaction fee
* transfer\_amt\_in\_dollars: Amount credited to your bank account after transaction fee deduction
* stripe\_fee\_in\_dollars: Transaction fee charged by Stripe
* bank\_fee\_in\_dollars: Transaction fee charged by the bank
* transaction\_id: Stripe's transaction ID
* currency: SGD only
* payment\_method: Indicates payment method (card for Stripe payments, paynow for bank PayNow)
* payment\_reference: Reference ID of the payment, input during creation of payment link

For Stripe's payout reports:

* card\_funding: Debit or credit
* card\_country: Issuing country for credit card
* card\_brand: Brand of card

For banks' payout reports:

* qr\_reference: Bank PaySG ID, displayed on payers' and agency's bank statement and on the payment page


# Payment workflows with Plumber

This section guides users on creating payment workflows with Plumber.

Using FormSG and PaySG on [Plumber](https://www.plumber.gov.sg), users can:

* Automate the creation of payment links using FormSG responses
* Automate the sending of default PaySG emails or customised emails on Postman
* Create payment forms

## Demonstrations

* For payment link creation: [go.gov.sg/paysg-plumber-demo](https://go.gov.sg/paysg-plumber-demo).&#x20;
  * Once the form is submitted, a PaySG payment email will be sent to the subject's email.
* For payment link and fine letter generation: [go.gov.sg/paysg-fine-demo](https://go.gov.sg/paysg-fine-demo).
  * Once the form is submitted, an email with a PDF fine that includes a PaySG QR code will be sent to the subject's email.


# Set-up

{% hint style="danger" %}
As of 25 June 2025, the PaySG team will not be issuing API keys for new users until further notice.
{% endhint %}

## Instructions&#x20;

To automate payment creation using FormSG's form responses, follow the instructions in the [Creating a form and payment service ](#creating-a-form-and-payment-service)and [Plumber set-up sections](#plumber-set-up).

To automate the above ***and*** the sending of emails or e-letters to payers, follow the instructions in the [Creating a form and payment service](#creating-a-form-and-payment-service), [Plumber set-up](#plumber-set-up) and Sending [emails](#sending-emails) / [letters](#sending-letters) sections.

## Creating a form and payment service

You will need:

1. A form and its corresponding secret key.&#x20;
2. A payment service and an API key, issued to you by the PaySG team (go.gov.sg/contact-paysg)

### Form creation

1. Create a storage mode form on FormSG and **save your secret key securely**. You’ll need this to view responses and to link the form to Plumber.&#x20;
2. The following fields should be included in your form, as these will be used in PaySG to create your payment link later on. These fields are included in the template provided. The fields may be renamed if necessary, but the details must either be collected through the form or manually input in Plumber ([Creating payments with PaySG](#creating-payments-with-paysg)).
   1. **Reference ID**&#x20;

      If not required for your use case, you can manually input a placeholder (e.g. N.A.) on Plumber.
   2. **Name**
   3. **Payment amount**

      For forms without fixed responses/dropdown, use a "Decimal" field on FormSG and enable Number validation to only accept values ≥ 0.50 and <= 999999,99 (card payments) / 200000 (PayNow payments).&#x20;
   4. The following fields are ***optional:***
      1. **Email**&#x20;

         Note that PaySG sends automated payment receipt emails only if an email is included. If an email is not included, payers will not receive payment receipt emails. They may reference the original payment link to view receipts after successful payment.
      2. **Address**
      3. **Identifier (e.g. NRIC/FIN)**

### Payment service creation

1. For one-time payments, follow the steps in our [payment service creation](/start-using-the-dashboard/payment-services) guide. For subscriptions, follow the steps in our [subscriptions](/start-using-the-dashboard/subscriptions) guide.
2. Log in to staging.pay.gov.sg and pay.gov.sg before contacting us (go.gov.sg/contact-paysg) to get an API key. You will need this to connect the payment service to Plumber.  Ensure that you include the email address for the API key to be issued to. You may refer to our [FAQ on API keys](/faq/api-keys) for more information.

## Plumber set-up

### Accepting FormSG responses

Follow the interactive demo below or refer to Plumber's [guide](https://guide.plumber.gov.sg/user-guides/actions/paysg) to learn how to connect FormSG and PaySG on Plumber to create payment links.

{% embed url="<https://app.arcade.software/share/NjCC73aLeaMNrUOlrwE4>" %}

### Converting payment amount into cents

The payment amount from your form must be converted into cents before you can create payment links using PaySG.

{% embed url="<https://app.arcade.software/share/7g9dgXdgyeIroo3oWAlK>" %}

### Creating payments with PaySG

Follow the interactive demo below or refer to Plumber's [guide](https://guide.plumber.gov.sg/user-guides/actions/paysg) to learn how to connect PaySG and create payment links.

{% embed url="<https://app.arcade.software/share/iOB9EPqyFQ8CJsdHVIzV>" %}

<figure><img src="/files/uxSKXjqerh73Hq2t8cR6" alt=""><figcaption></figcaption></figure>

## Sending emails&#x20;

Follow the interactive demo below to send **PaySG's default payment emails:**

{% embed url="<https://app.arcade.software/share/yvvrDfEgQPqFayJGJ8do>" %}

Follow the interactive demo below to send **customised emails using Postman**:

{% embed url="<https://app.arcade.software/share/BJOJvFBQZEI3DiYEyFP4>" %}

## Sending letters

You may view a demonstration at [go.gov.sg/paysg-fine-demo](https://go.gov.sg/paysg-fine-demo). Please use your gov.sg email for form input.

* [Submit your letter template to LetterSG.](https://go.gov.sg/lettersg-onboarding)
* Once you've been onboarded to LetterSG, refer to Plumber's guide on [connecting LetterSG to Plumber](https://guide.plumber.gov.sg/user-guides/actions/lettersg).


# Testing

To verify that your payment flow is working correctly:

* For the creation of payment links: Ensure that a payment link is created on PaySG's dashboard with the correct form details.&#x20;
* For the sending of payment/Postman emails: Ensure that an email is successfully received after form submission.

Once verified, you may create a live payment service at [pay.gov.sg](https://pay.gov.sg). You may choose to create a new pipe, or add a new connection for the live payment service instead of the staging payment service.

## Troubleshooting

#### Plumber

* Once you've verified that all the steps were followed accordingly, check if your pipe has been published. If your pipe's status is "Draft", your pipe has not been published yet. Access the selected pipe and click "Publish" in the top right corner.

<figure><img src="/files/kx0ooDMsF0EB5ODkns4j" alt=""><figcaption></figcaption></figure>

* For payment flows with unexpected results, check the "Executions" tab on Plumber for executions with a "Failure" status.

<figure><img src="/files/GSWaU3S32p3LA68LOKP4" alt=""><figcaption></figcaption></figure>

#### PaySG

<figure><img src="/files/tP4RUleGzYHl4VNf13YE" alt=""><figcaption><p>PaySG error</p></figcaption></figure>

Ensure that all [compulsory fields](/start-using-the-dashboard/one-time-payment-links/single-link-creation) are filled in. You may do so using a form response or by inputting a fixed value on Plumber.

#### Calculator

<figure><img src="/files/JL6XVwnvpaZbjajUiFgJ" alt=""><figcaption><p>Missing value in "firstNumber"</p></figcaption></figure>

<figure><img src="/files/iWJToO7N1BL9utOqzBqc" alt=""><figcaption><p>Calculator error message</p></figcaption></figure>

Ensure that all fields are filled in.&#x20;

For forms with **optional** payment amount fields, having an empty result will cause the pipe to fail. To prevent this, add a "0" in front of the selected result.

<figure><img src="/files/YKL7043fqcTd1n4FFJDx" alt=""><figcaption></figcaption></figure>


# Payment forms

## Introduction

Using FormSG, PaySG and Plumber, users can now create payment forms to collect one-time payments or create recurring payments. This workflow uses the form input to automatically create and redirect users to a payment link.

The payment flow is as follows:

* Payer accesses payment form and selects payment amount.
* Payer submits form.
* Payer is redirected to payment page to complete payment.

View the [payment form demo](https://go.gov.sg/paysg-paymentform-demo)

### What's the difference between payment forms and other payment workflows with Plumber?

* Payment forms redirect payers to make payment within the same page of form submission. Without successful payment, the form cannot be submitted.
* Other [Plumber payment workflows](/start-using-the-dashboard/payment-workflows-with-plumber) ([go.gov.sg/paysg-plumber-demo](https://go.gov.sg/paysg-plumber-demo), [go.gov.sg/paysg-fine-demo](https://go.gov.sg/paysg-fine-demo)) send out payment emails to payers, and the form can be submitted without successful payment. The payment flow is as follows:
  * Payer accesses the form and selects payment amount.
  * Payer submits form.
  * Payer receives a payment email.
  * Payer opens payment email to complete payment.
* Currently, subscriptions can only be initiated via a payment forms workflow with Plumber.


# Set-up

Payment forms use 3 platforms: PaySG, FormSG, and Plumber. You'll need to do some set up on each platform.

**What you'll need to do:**

1. Create a FormSG form with our required fields
2. Create a pipe on Plumber to transform each form submission to a payment amount
3. Connect your form to PaySG

This guide will take you through each step and its setup.

## Creating a form and payment service

You will need:

1. A form and its corresponding secret key.&#x20;
2. A payment service and an API key, issued to you by the PaySG team (go.gov.sg/contact-paysg)

## Form creation

[Create a storage mode form](https://guide.form.gov.sg/user-guides/basic-guide/create-form/create-form) on FormSG and **save your secret key securely**. You’ll need this to view responses and link the form to Plumber. Use our [form template](https://form.gov.sg/admin/form/67d11500186c9746b6ee0863/use-template) to get started.

#### **Form field setup**

The following fields should be included in your form, as these will be used in PaySG to create your payment link later on. You can rename the fields if necessary, but the details must either be collected through the form or manually input in Plumber.

All fields are already included in our [form template](https://form.gov.sg/admin/form/67d11500186c9746b6ee0863/use-template).&#x20;

Singpass and  Myinfo logins are not supported.

1. **Reference ID**  (corresponds to FormSG Reference Field Answer on Plumber)

   1. This field must be included for security purposes and to [connect your form to a payment service](#connecting-your-form-to-your-payment-service). You may refer to the screenshot below to retrieve your reference ID value when necessary.
   2. This is a "Short answer" field with "Enable pre-fill" and "Prevent pre-fill editing" enabled.&#x20;
      1. **Important:** When the form is complete, verify that the pre-fill field is **not open to editing.**
   3. PaySG will automatically pre-fill this field with a unique ID for each form submission.

   <figure><img src="/files/CKRapOyeGhjAmQZoGxCk" alt="" width="325"><figcaption></figcaption></figure>
2. **Name**
3. **Payment amount**
   1. For forms without fixed responses/dropdown, use a "Decimal" field on FormSG and enable Number validation to only accept values  ≥ 0.50 and <= 200,000.
4. **Email (Compulsory for subscriptions)**

The following fields are optional:

1. Email (Optional only for one-time payments)
   1. Note that PaySG sends automated payment receipt emails only if an email is included. If an email is not included, payers will not receive payment receipt emails. They may reference the original payment link to view receipts after successful payment.
2. Address
3. Identifier (e.g. NRIC/FIN)

### Payment service creation

1. Set up a payment service depending on your needs
   1. [Payment Service Creation](/start-using-the-dashboard/payment-services) for **one-time payments**, or
   2. [Subscriptions](/start-using-the-dashboard/subscriptions) for **recurring payments**.
2. Contact us at [**go.gov.sg/contact-paysg**](https://go.gov.sg/contact-paysg) to get an API key. Include the email address that you'd like the API key to be issued to. You may refer to our [FAQ on API keys](/faq/api-keys) for more information. Ensure that you save the API key securely.

## Plumber set-up

### Accepting FormSG responses

Follow the interactive demo below or refer to Plumber's guide to [learn how to connect FormSG and PaySG on Plumber](https://guide.plumber.gov.sg/user-guides/actions/paysg) to create payment links.

{% embed url="<https://app.arcade.software/share/NjCC73aLeaMNrUOlrwE4>" %}

### Converting payment amount into cents

The payment amount from your form must be converted into cents before you can create payment links using PaySG.

{% embed url="<https://app.arcade.software/share/7g9dgXdgyeIroo3oWAlK>" %}

## Connecting your form to your payment service&#x20;

In order to complete the Plumber set-up, you'll need to connect your form on PaySG.

{% embed url="<https://app.arcade.software/share/ObDVynPVB8MpvyjXg5lT>" %}

## Retrieve your payment form link

Once you've connected your form, retrieve the payment form link to complete the Plumber set-up.

{% hint style="danger" %}
All form submissions and payments **must be made via the payment form link** provided on PaySG's dashboard.&#x20;

**Do not use the original FormSG link** as it will not redirect payers to a payment page.
{% endhint %}

<figure><img src="/files/DR5HPPipuDRRaYYlcabM" alt=""><figcaption></figcaption></figure>

1. Access your payment service.
2. Access the "Forms" tab under your payment service and select the connected form.
3. Copy the Payment form link.

### Creating payments with PaySG

Now that your pipe can accept FormSG responses and transform the payment amount, follow the interactive demo to complete your Plumber set-up with PaySG.&#x20;

{% embed url="<https://app.arcade.software/share/JL46NNKPDQ8fKuHLCqvg>" %}

By default, only payment information is included in [PaySG's reports](/start-using-the-dashboard/reports). To include information from a form response in the report, select the relevant fields under the "Additional responses" section of the "Create payment form submission" action.

* Ensure that the selected FormSG questions are **not optional. If optional FormSG responses are included, the Plumber set up will not execute successfully.**

<figure><img src="/files/N7RM1Oji0F3vvIUjXEFR" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Ensure that you **publish your pipe** before proceeding to the next step.
{% endhint %}

### Collecting payments with payment forms

Once you've published your Plumber pipe, [retrieve your payment form link](#retrieve-your-payment-form-link) and begin collecting payments.


# Testing

1. Ensure that the steps in the [set-up section](/start-using-the-dashboard/payment-forms/set-up) were followed accordingly.
2. Submit a form response using your [payment form link](/start-using-the-dashboard/payment-forms/set-up#retrieve-your-payment-form-link) and ensure that you are redirected to a payment page with the correct details.  You may try out our demos for [one-time payments](https://go.gov.sg/paysg-paymentform-demo) and [subscriptions](https://go.gov.sg/paysg-subscriptions-demo) for reference.
3. If your form does not redirect you as expected, refer to the [Troubleshooting section in our Plumber testing guide](/start-using-the-dashboard/payment-workflows-with-plumber/testing) for common errors.&#x20;
4. Once you've completed steps 1 - 3, contact us (go.gov.sg/contact-paysg) if you require further assistance.&#x20;
   1. Add **<team+paymentforms@pay.gov.sg>** as a collaborator to your payment service and form. Please do not add <team@pay.gov.sg>.
   2. Include the pipe URL in your email.
   3. Ensure that your pipe is published - do not make changes to the pipe once you've reached out to us.


# Resources

Once your payment forms have been created and are used to collect payments, you may download various resources from PaySG to keep track of both the form responses and payments.

1. Payment reports
   1. Under the "Payments" tab, users can download [payment reports](/start-using-the-dashboard/reports#on-demand-payment-reports). These reports include payment information and Additional responses from your Plumber pipe.
2. Form responses
   1. Under the "Forms" tab, users can download form responses. This allows users to view all form information without having to access FormSG.
3. Payout reports
   1. Under the "Payouts" tab, users can download [payout reports](/start-using-the-dashboard/reports#payout-reports).&#x20;


# Get started

{% hint style="danger" %}
As of 25 June 2025,\
\
PaySG will not be onboarding new users until further notice. Users may onboard to our dashboard independently using the resources in the [Payment services section](/start-using-the-dashboard/payment-services) but onboarding support will not be available. Use cases that require API keys and webhooks will not be able to onboard during this period. \
\
We remain fully operational for existing users and will continue to assist with critical technical issues, such as payment failures or unexpected system behaviours on PaySG’s end.
{% endhint %}

PaySG APIs allows agencies to integrate the platform into their software systems. The API follows REST semantics, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. We do not provide SDKs.

Backwards compatibility is maintained within each major version of the API (`/v1`, `/v2`). However, new fields might be added as more features are developed on PaySG platform.

### 1. Introduction

Ensure that the onboarding steps in [this section](/) have been completed.

The rest of this guide walks you through setting up your integration with PaySG.

### 2. Create a payment service

To begin, follow our [payment service guide](/start-using-the-dashboard/payment-services) and create a payment service on our testing environment ([staging.pay.gov.sg](https://staging.pay.gov.sg)). All .gov.sg email addresses can do so without needing to create an account.&#x20;

### 3. Whitelisting

If you are a vendor, please request for your agency counterpart to contact us to whitelist your email addresses for access to our staging environment.&#x20;

### 4. API keys

Provide our team with the relevant gov.sg email addresses to receive an API key. **This email address must have been used to log in to PaySG's** [**staging (test) environment**](https://staging.pay.gov.sg/admin/services) **or** [**live environment**](https://pay.gov.sg/admin/login) **before, so that it is associated with a user.**&#x20;

Staging API keys have the prefix `paysg_stag_` while the live API keys have the prefix `paysg_live_`. **Payments should be tested on the staging environment using** [**dummy credit card numbers.** ](https://stripe.com/docs/testing)

To make authenticated requests, provide an **`x-api-key: <key>`** header to the request.

All API requests **must be made over HTTPS**. Calls made over plain HTTP will fail. API requests without authentication will also fail.

### 5. Test out our endpoints

Refer to our [documentation on endpoints ](/start-an-api-integration/endpoints)to send your first request.


# Endpoints

{% hint style="warning" %}
**Expected inputs and sample responses for each endpoint can be found** [**here**](https://api-staging.pay.gov.sg/external/api)**.**&#x20;

**All testing should be done on test mode only.** Test mode base URL: <https://api-staging.pay.gov.sg>

**Live mode base URL:** <https://api.pay.gov.sg>&#x20;
{% endhint %}

The paymentServiceID for your created payment service can be found as highlighted below. Please note that you will need to include the `payment_service` prefix.

<figure><img src="/files/OnLs786WeBtxMLoWaYrQ" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="112.33333333333331">Method</th><th width="391">Path</th><th>Purpose</th></tr></thead><tbody><tr><td><strong>GET</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments/{paymentId}</code></td><td>Fetches the payment with the given ID.</td></tr><tr><td><strong>GET</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments</code></td><td>Lists the payments for the given payment service.</td></tr><tr><td><strong>POST</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments</code></td><td>Creates a new payment.</td></tr><tr><td><strong>POST</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments/{paymentId}/cancel</code></td><td>Cancels the payment with the given ID. Only unpaid payments can be cancelled.</td></tr><tr><td><strong>POST</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments/{paymentId}/send-email</code></td><td>Emails the payment with the given ID to the payer through their email.</td></tr></tbody></table>


# Integrating with your e-services

The following describes what you can expect when integrating your e-service with PaySG.

{% hint style="info" %}
**Expected inputs and sample responses for each endpoint can be found** [**here**](https://api-staging.pay.gov.sg/external/api)**.**&#x20;
{% endhint %}

{% hint style="info" %}
Integration FAQs can be found [here](/faq/api-integration).
{% endhint %}

## Integrated payment flow&#x20;

<figure><img src="/files/kUaLsp0n1vmgitkvBDQ6" alt=""><figcaption><p>Sample integrated payment flow</p></figcaption></figure>

The following describes the overall flow of how a successful payment integration would work when a payer enters your e-service to make a payment.

#### Creating a payment

1. The payer accesses your e-service.
2. Your e-service initiates a payment on PaySG through a POST API call to the relevant endpoint to create a new payment. If necessary, your team can include a `return_url` which will be used to redirect users after successful payment. Please note that the `return_url` must be a valid HTTPS URL, otherwise, the payment creation will be blocked by PaySG.
3. The PaySG server returns a payment object to your e-service.
4. Your e-service then needs to redirect the payer to the `payment_url`, found in the payment object, which leads to PaySG's payment page.
5. The payer completes the payment on the PaySG payment page. Payment links **will remain valid** until cancelled on the dashboard/via API or when payment succeeds.

#### (Optional) Redirecting payers back after successful payment

1. Upon successful payment, the PaySG payment page redirects the payer back to the `return_url` provided by your team. Please note that the `return_url` must be a valid HTTPS URL, otherwise, the payment creation will be blocked by PaySG.
2. Your e-service receives the `paysg_payment_id` and `paysg_payment_service_id` and makes a GET API call to PaySG to verify the payment status. [Webhooks](/webhooks/introduction) are also available.
3. The PaySG server responds by returning the payment status.
4. If the payment status is confirmed as paid, your e-service marks the payment as paid and allows the payer to continue with their e-service flow.

#### Checking Payment Status

* Send a GET request using the `id` and `payment_service_id.` &#x20;
* Alternatively, set up a [webhook](/webhooks/introduction) to receive updates of successful payments.


# Errors

PaySG uses conventional HTTP response codes to indicate the success or failure of an API request.

In the event of an error occurring, the server will respond with the appropriate error HTTP status code along with a JSON response body containing details about the error that has occurred.

## HTTP Status Codes

Generally, codes in the `4XX` range indicate an error that occurred due to the information provided (e.g. invalid input, rate limit exceeded). Codes in the `5XX` range indicate an error within PaySG’s servers (this should be rare).&#x20;

Conventional HTTP response codes are used to indicate the success or failure of an API request.&#x20;

<table><thead><tr><th width="246">HTTP Status Code</th><th>Description</th></tr></thead><tbody><tr><td>400 - Bad Request</td><td>The request was unacceptable, often due to a missing required parameter or an unexpected format.</td></tr><tr><td>401 - Unauthorized</td><td>No valid credentials provided.</td></tr><tr><td>402 - Request Failed</td><td>The parameters were valid but the request failed. 402 is not a clearly defined HTTP code, but in certain APIs is used when a resource’s state is concerned. (eg. Payment service is not connected to a stripe account).</td></tr><tr><td>403 - Forbidden</td><td>Your credentials doesn’t have permissions to perform the request.</td></tr><tr><td>404 - Not Found</td><td>The requested resource doesn’t exist.</td></tr><tr><td>409 - Conflict</td><td>The request conflicts with another request (eg. same idempotent key).</td></tr><tr><td>429 - Too Many Requests</td><td>Too many requests. We recommend an exponential backoff.</td></tr><tr><td>500 - Server Error</td><td>Something went wrong on PaySG's end</td></tr><tr><td>503 - Server Error</td><td>Something went wrong on PaySG’s end, caused by an external service</td></tr></tbody></table>

## Response Body

The response body will be a a JSON containing a nested `error` object with the following properties:

<table><thead><tr><th width="185.33333333333331">Property</th><th width="142">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>The broad category in which this error belongs to in snake-case.</td></tr><tr><td><code>code</code></td><td>string</td><td>The identifier of the error that has occured in snake-case.</td></tr><tr><td><code>message</code></td><td>string</td><td>A human readable string explaining the error that has occurred.</td></tr><tr><td><code>data</code> (optional)</td><td>JSON Object</td><td>An optional nested JSON object that contain additional contextual information about the error. </td></tr></tbody></table>

To identify the specific error that has occurred, integrators may look at the `code` field in the `error` object.

### Sample Response

The following is a sample response body returned by the server when an invalid email address has been provided as part of a request.

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "Param error. Email violates validation"
  }
}
```

### Error Types (error.type)

The following is a list of possible error types. This will be present in the `type` field of the `error` object.

<table><thead><tr><th width="266">error.type</th><th>Description</th></tr></thead><tbody><tr><td><code>api_error</code></td><td>API errors indicate an issue with PaySG's servers.</td></tr><tr><td><code>external_error</code></td><td>External errors indicate an issue due to an external service utilized by PaySG, which prevented PaySG from completing the request (Eg. Stripe, Postmark, etc.).</td></tr><tr><td><code>idempotency_error</code></td><td>Idempotency errors occur when an <code>Idempotency-Key</code> is re-used on a request that does not match the first request's API endpoint and parameters or when the first request is still processing.</td></tr><tr><td><code>invalid_request_error</code></td><td>Invalid request errors arise when your request has invalid parameters.</td></tr></tbody></table>

### Errors Codes (error.code)

The following is a non-exhaustive list of possible error codes. This will be present in the `code` field of the `error` object.

<table><thead><tr><th width="295">error.code</th><th>Description</th></tr></thead><tbody><tr><td><code>parameter_invalid</code></td><td>A parameter provided in the request has failed validation</td></tr><tr><td><code>api_key_invalid</code></td><td>The API Key provided is invalid</td></tr><tr><td><code>email_blacklisted</code></td><td>Email address has been blacklisted by either PaySG or our email provider. This is commonly due to previous attempts to send to this email address being rejected.</td></tr><tr><td><code>authentication_required</code></td><td>Authentication is required for this request</td></tr><tr><td><code>api_key_expired</code></td><td>The API Key provided has expired</td></tr><tr><td><code>stripe_connect_account_not_found_for_payment_service</code></td><td>The payment service has no Stripe connect account connected to it which is required.</td></tr><tr><td><code>payment_not_found</code></td><td>A payment with the ID provided cannot be found.</td></tr><tr><td><code>payment_service_not_found</code></td><td>A payment service with the ID provided cannot be found.</td></tr><tr><td><code>user_forbidden</code></td><td>The user making this request is not allowed to carry out this operation.</td></tr><tr><td><code>idempotent_request_in_progress</code></td><td>A request with the same idempotency key is currently being processed.</td></tr><tr><td><code>idempotent_request_body_mismatch</code></td><td>Request body does not match initial request with the same idempotency key</td></tr><tr><td><code>server_error</code></td><td>An internal error has occurred on PaySG servers</td></tr></tbody></table>


# Idempotency

Some of our HTTP POST API endpoints support idempotency to allow safe retries without unintentionally attempting an operation multiple times. This is useful when the API call is disrupted in transit and a response is not received.

## Supported Endpoints

We support idempotency for the following endpoints:

<table><thead><tr><th width="112.33333333333331">Method</th><th width="391">Path</th><th>Purpose</th></tr></thead><tbody><tr><td><strong>POST</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments</code></td><td>Creates a new payment.</td></tr><tr><td><strong>POST</strong></td><td><code>/v1/payment-services/{paymentServiceId}/payments/{paymentId}/refund</code></td><td>Refunds a payment</td></tr></tbody></table>

## Implementation and Details

To perform an idempotent request, provide an additional **`Idempotency-Key: <key>`** header to the  request.

PaySG idempotency key works by saving the resulting status code and body of the first request made for any given idempotency key, regardless of whether it succeeded or failed. Subsequent requests with the same key return the same result, including **`500`** errors.

An idempotency key is a unique value generated by the client which the server uses to recognize subsequent retries of the same request. How you create unique keys is up to you, but we suggest using V4 UUIDs, or another random string with enough entropy to avoid collisions. Idempotency keys can be up to 255 characters long.

Keys are eligible to be removed from the system automatically after they are at least 24 hours old, and a new request is generated if a key is reused after the original has been pruned. The idempotency layer compares incoming parameters to those of the original request and errors unless they're the same to prevent accidental misuse.

Results are only saved if an API endpoint started executing. If incoming parameters failed validation, or the request conflicted with another that was executing concurrently, no idempotent result is saved because no API endpoint began execution based on the current request. It is safe to retry these requests.


# Pagination

#### API endpoints that support pagination

| API                                                                                                    | Sorted Order                                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Get all payments from payment service](/api-resources/payments/get-all-payments-from-payment-service) | <ul><li><code>created\_at</code></li><li><code>id</code></li></ul><p>Returns the most recently created payments first. If multiple payments are created at the same time, they are returned in reverse alphabetical order of their <code>id</code></p> |

We use cursor-based pagination for endpoints that list resources. The cursors used for pagination have **no inherent relationship** to the resources. These endpoints share a common structure, accepting the following parameters: `limit`, `before` and `after` . The response includes: `data` , an array containing the current page of resources, and `page_info` , which holds information about the current page.\
\
The `page_info` object contains a `start_cursor` that points to the first resource of the current page, `end_cursor` which points to the last resource of the current page, `has_previous_page` and `has_next_page` which indicate if the resource has a previous and next page respectively. \
\
Each cursor can be passed into  either the `before` or `after` parameters to return the resources immediately before or after the provided cursor. These parameters are mutually exclusive. You can use either the `before` or `after` parameter, but not both simultaneously. If **both** `before` and `after` are passed, an error will be returned by the API server. If no cursors are passed into `before` or `after`, the API returns the first page, containing the newest resources.&#x20;

#### Sample Response

```json
{
  "data": [ ... ]
  "page_info": {
    "has_next_page": true,
    "has_previous_page": true,
    "start_cursor": "WyIyMDIzLTA1LTEyVODowMCIsIjaaB0NCDE0OjI3Z25QRXVyYm9YTldOjEyLjczNCswaTzk5QyJd",
    "end_cursor": "WyIyMDdOjEyLjczLTA1LTjI3Z25QRXVyYm9YVODIzDE0Ok5QyJdTlowMCIsIjaaB0NCNCswaTzEy",
  }
}
```

#### Sample Usage

```
// Referencing the sample response

// Using before
// Calling GET /v1/payment-services/:payment_service_id?limit=20&before=${start_cursor}
Returns the previous page of resources and its page information

// Using after
// Calling GET /v1/payment-services/:payment_service_id?limit=20&after=${end_cursor}
Returns the next page of resources and its page information

```


# Go-live checklist

**The following steps should be completed 1 week before your go-live date.**

1. Create your payment service at [pay.gov.sg](http://pay.gov.sg/) and retrieve the payment service ID from the URL.&#x20;

<figure><img src="/files/bGC60avn7S9ANuvMxBnz" alt=""><figcaption></figcaption></figure>

2. Select an email address for the API key to be issued to. We recommend using a group email address (e.g. <agency_finance_team@agency.gov.sg>) for transferability.
3. (Optional) For webhook registration, share the webhook URL with the PaySG team.

**You will need to share the following information with PaySG (<team@pay.gov.sg>):**

* Payment service ID
* Email address for API key
* (optional) Webhook URL
* For agencies with DBS PayNow integrations:
  1. Payment service ID
  2. Agency UEN
  3. DBS account number
  4. DBS API key (provided by DBS)
  5. DBS organisation ID (provided by DBS)

**You will receive the following resources from PaySG:**

* API key
* (optional) Webhook secret


# Events

PaySG uses events to notify you when something interesting happens in your payment service. When an interesting event occurs, PaySG creates a new `Event` object. For example, when a payer successfully completes payment on PaySG, PaySG creates a payment.succeeded event.

PaySG also has a separate [webhooks ](/webhooks/introduction)system for sending the Event objects directly to an endpoint on your server. You can manage webhooks in your payment service settings. Learn how to listen for events so that your integration can automatically trigger reactions.


# The event object

**Attributes**

***

**id** string

Unique identifier for the object.

***

**data** hash

Object containing data associated with the event.

<details>

<summary>show child attributes</summary>

**data.object** hash

Object containing the API resource relevant to the event. For example, an `payment.succeeded` event will have a full payment object as the value of the `object` key.

</details>

***

**type** string

Description of the event (for example, `payment.succeeded` )

***

#### More attributes

***

**object** string, value is "event"

String representing the object’s type. Objects of the same type share the same value.

***

**payment\_service\_id** string

The payment service that originates the event.

***

**created** timestamp

Time at which the object was created. Measured in milliseconds since the Unix epoch.


# Types of events

PaySG sends a variety of event types to inform you of activity in your payment service. These events follow a consistent pattern of `resource.event`. More events may be added at any time, so in developing and maintaining your code, you should not assume that only these types exist.

## Event

***

#### payment.succeeded&#x20;

Occurs whenever a payer successfully completes their payment on PaySG.

<br>


# Payments

`Payments` on PaySG facilitates payment collection from a Member of Public (MOP) and/or businesses. We recommend that you create one payment link for each bill or payment request within the payment service. A `payment service` is a group or collection of payments of similar nature or type. You may reference the payments within a payment service from PaySG's admin dashboard for an overview of all payment requests/transactions made before.


# Create a payment

Creates a payment object.

After the payment is created, the payer will have to click on 'Proceed' to select the payment method, fill in their payment details and confirm to complete the payment transaction.

**Parameters**

***

**reference\_id** required

The agency’s reference id in their preferred format. Invoice number is commonly used. It should not exceed a **maximum of** **255 characters**.

***

**payer\_name** required

Name of citizen or company making the payment. It should not exceed a **maximum of** **255 characters**.

***

**payer\_address** optional

Address of citizen or company making the payment. It should not exceed a **maximum of** **255 characters**.

***

**payer\_identifier** optional

Tax identifier of payer. e.g. NRIC, UEN. It should not exceed a **maximum of** **10 characters**.

***

**payer\_email** optional

Email address that should receive the payment link and invoice. It should not exceed a **maximum of** **255 characters**.

***

**description** required

Description of what the payment is for. This will be shown to the payer in the payment link. It should not exceed a **maximum of** **500 characters**.

***

**amount\_in\_cents** required

The total amount that the citizen or company should pay. It **should not exceed 20000000 cents ($200,000).**

***

**due\_date** optional

Expected due date for the payment. This will be displayed in emails and reminders sent to the payer. It should be in the format `dd-MMM-yyyy`. e.g. 31-DEC-2023.

***

**metadata** optional

Additional metadata related to this payment. Metadata only supports up to 10 entries. Keys must be at **most 40 characters long.** Values must be at most **255 characters long**.

Example:

```json
"metadata": {
		"branch_code": "123",
		"pos_ID": "456",
		"cashier_ID": "001",
		"receipt_number": "789"
	}
```

**line\_items** optional

***

Line item breakdown of the payment. Unlimited entries are supported. The description key must not exceed **255 characters**.  The total amount for all line items **should not exceed 20000000 cents ($200,000)**.&#x20;

Example:

```json
"line_items": [
    {
      "description": "Payment for season ticket",
      "quantity": 10,
      "unit_amount_in_cents": 100
    }
  ]
```

#### Returns

***

Returns a `payment` object.

The `payment` object will be the payment to be created.

#### POST /v1/payment-services/:payment\_service\_id/payments

***

```json
{
    "reference_id": "PAYMENT_001",
    "payer_name": "Andy Lau",
    "payer_address": "Blk 123, Yishun Avenue 2, #08-88, Singapore 123456",
    "payer_identifier": "S1234567A",
    "payer_email": "abc@gmail.com",
    "description": "Payment for XXX",
    "amount_in_cents": 1100,
		"due_date": "31-DEC-2023", // optional
		"return_url": "https://open.gov.sg" //optional
    "metadata": {
			"product code": "123" // can add other key-value pairs here
		}
}
```

**RESPONSE**

```json
{
    "id": "ZbzTvadjmP0wd7RRxhWtj",
    "due_date": null,
    "metadata": {
			"product code": "123",
		},
    "payout_id": null,
    "created_at": "2023-08-03T17:36:52.634+08:00",
    "creator_id": "user_xxx",
    "payer_name": "Andy Lau",
    "updated_at": "2023-08-03T17:36:52.634+08:00",
    "description": "Payment for XXX",
    "payer_email": "abc@gmail.com",
    "payment_url": "http://pay.gov.sg/payments/ZbzTvadjmP0wd7RRxhWtj",
		"return_url": "https://open.gov.sg"
    "reference_id": "PAYMENT_001",
    "latest_status": "unpaid",
    "payer_address": "Blk 123, Yishun Avenue 2, #08-88, Singapore 123456",
    "refund_status": "not_refunded",
    "payment_status": "unpaid",
    "amount_in_cents": 1100,
    "payer_identifier": "S1234567A",
    "paid_out_timestamp": null,
    "payment_service_id": "payment_service_xxx",
    "email_delivery_status": "unsent",
    "payment_sent_timestamp": null,
    "stripe_payment_intent_id": "pi_xxx",
    "payment_cancelled_timestamp": null,
    "payment_succeeded_timestamp": null,
    "payment_fully_refunded_timestamp": null
}
```


# Retrieve payments

Retrieves the details of a payment that has previously been created.

#### Returns

***

Returns a `payment` if a valid identifier was provided.

#### GET /v1/payment-services/:payment\_service\_id/payments/:paymentId

***

**RESPONSE**

```json
{
    "id": "ZbzTvadjmP0wd7RRxhWtj",
    "due_date": null,
    "metadata": {},
    "payout_id": null,
    "created_at": "2023-08-03T17:36:52.634+08:00",
    "creator_id": "user_xxx",
    "payer_name": "Andy Lau",
    "updated_at": "2023-08-03T17:36:52.634+08:00",
    "description": "Payment for XXX",
    "payer_email": "abc@gmail.com",
    "payment_url": "http://pay.gov.sg/payments/ZbzTvadjmP0wd7RRxhWtj",
    "reference_id": "PAYMENT_001",
    "latest_status": "unpaid",
    "payer_address": "Blk 123, Yishun Avenue 2, #08-88, Singapore 123456",
    "refund_status": "not_refunded",
    "payment_status": "unpaid",
    "amount_in_cents": 1100,
    "payer_identifier": "S1234567A",
    "paid_out_timestamp": null,
    "payment_service_id": "payment_service_xxx",
    "email_delivery_status": "unsent",
    "payment_sent_timestamp": null,
    "stripe_payment_intent_id": "pi_xxx",
    "payment_cancelled_timestamp": null,
    "payment_succeeded_timestamp": null,
    "payment_fully_refunded_timestamp": null
}
```


# Send email for payment

Sends an email notification to intended payer with the details of a payment that has previously been created.

#### POST /v1/payment-services/:payment\_service\_id/payments/:paymentId/send-email

***

**RESPONSE**

```json
204 NO CONTENT
```


# Cancel a payment

Cancels a payment with an 'unpaid' status.

#### Returns

***

Returns a `payment` object if the cancellation succeeds. Returns an error if the `payment` is already canceled or isn’t in a cancelable state.

#### POST /v1/payment-services/:payment\_service\_id/payments/:paymentId/cancel

***

**RESPONSE**

```json
{
    "id": "ZbzTvadjmP0wd7RRxhWtj",
    "due_date": "31-DEC-2023",
    "metadata": {},
    "payout_id": null,
    "created_at": "2023-08-03T17:36:52.634+08:00",
    "creator_id": "user_xxx",
    "payer_name": "Andy Lau",
    "updated_at": "2023-08-03T17:36:52.634+08:00",
    "description": "Payment for XXX",
    "payer_email": "abc@gmail.com",
    "payment_url": "http://pay.gov.sg/payments/ZbzTvadjmP0wd7RRxhWtj",
    "reference_id": "PAYMENT_001",
    "latest_status": "cancelled",
    "payer_address": "Blk 123, Yishun Avenue 2, #08-88, Singapore 123456",
    "refund_status": "not_refunded",
    "payment_status": "cancelled",
    "amount_in_cents": 1100,
    "payer_identifier": "S1234567A",
    "paid_out_timestamp": null,
    "payment_service_id": "payment_service_xxx",
    "email_delivery_status": "unsent",
    "payment_sent_timestamp": null,
    "stripe_payment_intent_id": "pi_xxx",
    "payment_cancelled_timestamp": "2023-08-14T11:44:19.197+08:00",
    "payment_succeeded_timestamp": null,
    "payment_fully_refunded_timestamp": null
}
```


# Refund a payment

Refunds a payment with a 'paid' status.

Refunds can be:

1. Issued in full.
2. Issued in multiple partial refunds, as long as the refunded amount is within the received payment amount.  **Only a single refund will be processed at a time.**

Funds will be refunded through the payment method that the payment was made by.&#x20;

**Parameters**

***

**refund\_amount\_in\_cents** required

A positive integer representing the amount to refund.  The amount must not exceed the remaining refundable amount.

#### Returns

***

Returns a `payment` object if the refund succeeds. Returns an error if the `payment` object has already been fully refunded or has prior pending/failed refunds.

#### POST /v1/payment-services/:payment\_service\_id/payments/:paymentId/refund

***

**RESPONSE**

```json
{
    "id": "ZbzTvadjmP0wd7RRxhWtj",
    "due_date": "31-DEC-2023",
    "metadata": {},
    "payout_id": null,
    "created_at": "2023-08-03T17:36:52.634+08:00",
    "creator_id": "user_xxx",
    "payer_name": "Andy Lau",
    "updated_at": "2023-08-16T11:44:19.197+08:00"
    "description": "Payment for XXX",
    "payer_email": "abc@gmail.com",
    "payment_url": "http://pay.gov.sg/payments/ZbzTvadjmP0wd7RRxhWtj",
    "reference_id": "PAYMENT_001",
    "latest_status": "cancelled",
    "payer_address": "Blk 123, Yishun Avenue 2, #08-88, Singapore 123456",
    "refund_status": "fully_refunded",
    "payment_status": "paid",
    "amount_in_cents": 1100,
    "payer_identifier": "S1234567A",
    "paid_out_timestamp": null,
    "payment_service_id": "payment_service_xxx",
    "email_delivery_status": "sent",
    "payment_sent_timestamp": "2023-08-13T11:44:19.197+08:00",
    "stripe_payment_intent_id": "pi_xxx",
    "payment_cancelled_timestamp": "2023-08-14T11:44:19.197+08:00",
    "payment_succeeded_timestamp": "2023-08-15T11:44:19.197+08:00",
    "payment_fully_refunded_timestamp": "2023-08-16T11:44:19.197+08:00"
}
```


# Get all payments from payment service

Returns a list of payments created within a payment service.

#### Returns

***

A dictionary with a `data` property that contains an array of up to 20 payments. Each entry in the array is a separate `payment` object. If no other `payments` are available, the resulting array is empty.

#### GET /v1/payment-services/:payment\_service\_id?limit=20

***

**Payment Filtering**

Agencies can specify a string that they want to filter the payments to have **(only by Ref Id, Name, Email).** For example, specifying `search=abc@gmail.com` will filter payments with email `abc@gmail.com`.

**Pagination**

Additionally, the end point uses [cursor pagination](https://jsonapi.org/profiles/ethanresnick/cursor-pagination/) for retrieval of data. Results are sorted in ascending order of transaction creation date.


# Introduction

## Why use webhooks?

Webhooks are a useful tool when building PaySG integrations, as they allow your e-services to receive events in real-time as they occur in your payment service.

To enable webhook events, you will need to register webhook endpoints. Once registered, PaySG can push real-time event data to your application's webhook endpoint whenever [events](#event-object) happen in your PaySG account. PaySG uses HTTPS to send webhook events to your app as a JSON payload that includes an [Event object](/api-resources/events/the-event-object).

Receiving webhook events is particularly useful for listening to asynchronous events. The current version of webhooks supports events for when a payer has paid.

## Overview

To begin receiving webhook events in your application, you can create and register a webhook endpoint by following these steps:

1. Identify the specific events that you want to monitor.
2. Develop a webhook endpoint function that can receive event data POST requests on your e-service.
3. Register your endpoint with the PaySG team. For now, this can be done by contacting the team and providing the following fields for them. Before contacting us, **ensure that your endpoint's hostname resolves to a valid public IP address**, as we verify this before activating the webhook.
   * `webhook_url` the endpoint of your e-service that PaySG should send webhooks to.
   * `description` optional field for you to describe the webhook.
   * `subscribed_events` list of subscribed [events](/api-resources/events) from PaySG that your e-service would like to subscribe to.
4. Ensure that your webhook endpoint is secure to prevent unauthorized access.

[Refer to our next section on set up for more information.](/webhooks/set-up)


# Set-up

{% hint style="danger" %}
As of 25 June 2025, the PaySG team will not be setting up webhooks for new users until further notice.
{% endhint %}

1. Identify the events to monitor
2. Create a webhook endpoint function
3. Register and manage your webhook in PaySG
4. Secure your webhooks

## 1. Identify the events to monitor

Use the PaySG API reference to identify the PaySG events and the [Event objects](/api-resources/events/the-event-object) your webhook endpoint service needs to parse.

***

## 2. Create a webhook endpoint function

To set up a webhook endpoint function that can accept webhook requests with a POST method, you can follow these steps:

1. Create an HTTPS endpoint function that can handle POST requests with a JSON payload consisting of an [event object](/api-resources/events/the-event-object). Webhooks will only be supported for HTTPS endpoints.
2. Ensure that your endpoint function quickly returns a successful status code (2xx) prior to any complex logic that could cause a timeout. For example, you must return a 2xx response before updating your internal system records.

***

## 3. Register and manage your webhook in PaySG

After testing your webhook endpoint function, you can register the endpoint's accessible URL. Please add <team@pay.gov.sg> as an [admin](/start-using-the-dashboard/collaborators-and-access-control) to the payment service, and share the webhook endpoint(s) with us via [go.gov.sg/contact-paysg](https://go.gov.sg/contact-paysg). The webhook endpoint(s) **must be publicly accessible HTTPS URLs.**

#### Webhook URL format

The URL format to register a webhook endpoint is:

```
https://<agency-website>/<your-webhook-endpoint>
```

For example, if your domain is `https://agency-eservice.com` and the route to your webhook endpoint is `@app.route('/paysg_webhooks', methods=['POST'])`, specify `https://agency-eservice.com/paysg_webhooks` as the endpoint URL.

#### Manage a webhook endpoint configuration

To add, update or delete existing webhook endpoints, contact the PaySG team to do it for you.

## 4. Secure your webhooks

After confirming that your webhook endpoint connection works as expected, secure the connection by implementing [webhook best practices](/webhooks/set-up/best-practices).

One especially important best practice is to use webhook signatures to verify that PaySG generated a webhook request and that it did not come from a server acting like PaySG. The steps to validate PaySG's webhook signature can be found under [webhook best practices](/webhooks/set-up/best-practices#verify-events-are-sent-from-paysg). **PaySG does not support further customisation to verify specific values from your team.**

## 5. Network whitelisting (optional)

PaySG recommends that you verify authenticity of webhooks via signature validation. However, if your system requires IP whitelisting, you can use the following IP addresses.

\*\*Staging (<https://staging.pay.gov.sg)**\\>
13.215.25.150\
13.213.93.248

\*\*Production (<https://pay.gov.sg)**\\>
3.1.60.243\
13.229.175.148\
13.214.75.139

PaySG will inform you at least 1 month in advance of any changes to these IPs.


# Events

## Overview

PaySG generates event data that you can use to inform you of activity on your payment service. When an event occurs, PaySG generates a new [Event object](#event-object). For example, when a payer pays on PaySG, you receive `payment.succeeded` event.

By registering webhook endpoints in your payment service, you enable PaySG to automatically send [Event objects](#event-object) as part of **POST** requests to the registered webhook endpoint hosted by your application.&#x20;

#### Event Object

The Event object we send to your webhook endpoint provides a snapshot of the object that changed.

Currently, we only support the `payment.succeeded` event type.

#### Example event payload

{% code overflow="wrap" %}

```json
{
  "id": "evt_752ced1f-00ce-4905-8c46-367371dd78e6",
  "data": {
    "object": {
      "id": "wLAnFWQLYyYNKBimc2ZkA",
      "due_date": null,
      "metadata": {},
      "payout_id": null,
      "created_at": "2023-07-17T17:15:12.200+08:00",
      "creator_id": "user_655d26a2-ddfc-4718-a008-bd181c1522e8",
      "payer_name": "John Doe",
      "updated_at": "2023-10-02T16:17:08.167+08:00",
      "payer_email": "abc@gmail.com",
      "payment_url": "http://pay.gov.sg/payments/payment01",
      "description": "Payment for XXX",
      "reference_id": "INV001",
      "latest_status": "paid",
      "payer_address": "36 Robinson Road, Singapore 068877",
      "refund_status": "not_refunded",
      "amount_in_cents": 12.34,
      "payment_status": "paid",
      "payer_identifier": "S1234567A",
      "paid_out_timestamp": null,
      "payment_service_id": "payment_service_fd724c82-786b-43ba-b7d7-1eecab0388e1",
      "email_delivery_status": "sent",
      "payment_sent_timestamp": "2023-07-31T10:01:48.761+08:00",
      "stripe_payment_intentId": "pi_3NUnWOLRKRlnGcim1Nzy18Z0",
      "payment_cancelled_timestamp": null,
      "payment_succeeded_timestamp": "2023-10-02T16:17:08.164+08:00",
      "payment_fully_refunded_timestamp": null
    }
  },
  "type": "payment.succeeded",
  "object": "event",
  "created_at": "2023-10-02T16:17:08.210+08:00",
  "payment_service_id": "payment_service_fd724c82-786b-43ba-b7d7-1eecab0388e1"
}
```

{% endcode %}

#### Why event object gets generated

This table describes different scenarios that trigger generating events.

<table><thead><tr><th width="370">Source</th><th>Trigger</th></tr></thead><tbody><tr><td>PaySG platform</td><td>When a user action (i.e. pays) in the PaySG platform results in an API call</td></tr></tbody></table>

## Event delivery behaviours

This section provides documentation on the different behaviors that you can expect when PaySG sends events to your webhook endpoint. Specifically, it covers event retry deliveries and event ordering.

#### Retry behaviour

PaySG attempts to deliver an event to your webhook endpoint for up to 3 days with an exponential back off.&#x20;

If your endpoint has been deleted when PaySG attempts a retry, future retries of that event will be prevented.

#### Event ordering

PaySG doesn’t guarantee delivery of events in the order in which they’re generated.

Your endpoint should not expect delivery of events in order, and needs to handle out-of-order delivery accordingly.


# Best practices

Review these best practices to make sure your webhooks remain secure and function well with your integration

#### Verify events are sent from PaySG

Once your webhook has been registered, the PaySG team will provide you with your endpoint's secret. The secret is a unique value that is used to sign webhook events sent to your endpoint. You should use this secret to verify the signature of incoming webhook events to confirm that received events are sent from PaySG. PaySG signs webhook events that are sent to your endpoints by including a signature in each event's `PaySG-Signature` header.&#x20;

To verify webhook signatures, developers can follow these steps:

1. Extract the signature from the HTTP header called `PaySG-Signature`
2. The value of the header has the format `t=timestamp, v1=signature`. Extract the timestamp and the signature
3. Concatenate the timestamp and the JSON-stringified HTTP payload, separated by a `.` to form the signature payload
4. Use HMAC-SHA256 and the symmetric key provided to you by PaySG to verify that the signature is valid

#### Duplicate event handling

Webhook endpoints may receive the same event more than once, which can result in duplicated event receipts. To prevent this, it's important to make your **event** **processing idempotent**. One way to achieve this is by logging the events that you have already processed, and then not processing any events that have already been logged.&#x20;

#### Specifically listening to event types your integration requires

To optimize the performance of your webhook endpoints, it's recommended that you configure them to receive only the types of events that are required by your integration. Listening for extra events, or all events, can put undue strain on your server.

You can change the events that a webhook endpoint receives in the PaySG Dashboard.

#### Exempt webhook route from CSRF protection

For applications using Rails, Django, or another web framework, your site might automatically check that every POST request contains a *CSRF token as a* security feature to protect you and your users from [cross-site request forgery](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_\(CSRF\)) attempts. However, this might also prevent your site from processing legitimate events. In such cases, you might need to exempt the webhooks route from CSRF protection.

#### Preventing replay attacks

To prevent [replay attack](https://en.wikipedia.org/wiki/Replay_attack), PaySG includes a timestamp in the PaySG-Signature header. This timestamp is part of the signed payload and is verified by the signature, so an attacker cannot change the timestamp without invalidating the signature. If the signature is valid but the timestamp is too old, your e-service should reject the payload.

You can consider having a tolerance between the timestamp included in the header and the current time.

Note that if PaySG retries an event (for example, if your endpoint previously replied with a non-2xx status code), a new signature and timestamp will be generated for the new delivery attempt.

#### Verifying signatures manually

You can also create a custom solution by following these steps:

**Step 1: Extract the timestamp and signatures from the header**&#x20;

The `PaySG-Signature` header included in each signed event contains a timestamp and one or more signatures that you must verify. The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature (or signatures). To prevent [downgrade attacks](https://en.wikipedia.org/wiki/Downgrade_attack), ignore all schemes that are not `v1`.

```
PaySG-Signature:
t=, // timestamp
v1= // event-id
```

**Step 2: Prepare the signed\_payload string**&#x20;

The `signed_payload` string is created by concatenating:

* The timestamp (as a string) `t`
* The character `.`
* The actual JSON payload (i.e., the request body).

**Step 3: Determine the expected signature**&#x20;

Compute an [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) with the [SHA-256](https://en.wikipedia.org/wiki/SHA-2) hash function. Use the endpoint's signing secret as the key, and use the `signed_payload` string as the message.

**Step 4: Compare the signatures**&#x20;

Compare the signature in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance. To protect against timing attacks, use a constant-time-string comparison to compare the expected signature to each of the received signatures.


# Access

### Do I need to create an account to use PaySG?

No, any .gov.sg can be used to log in to PaySG without needing to create an account.

### I do not have a .gov.sg email. How can I access PaySG?

If you are a vendor working on integrating PaySG with a government agency, request for your agency counterpart contact us to whitelist your email address on our staging environment.

### Can multiple users have access to the payment service?

Yes, access to payment services can be updated in the [Collaborators section in the payment service's Settings.](/start-using-the-dashboard/collaborators-and-access-control)

### Can I set different access or permission levels for different users?

Yes, you may refer to our [Collaborators](/start-using-the-dashboard/collaborators-and-access-control) section for more information.

### I did not receive my OTP. Where is it?

The OTP is sent immediately, but might take a while to arrive in your government email if there is high traffic on the government network. If there are widespread OTP issues, we will inform admins via our communication channels.

{% hint style="info" %}
If you have already requested a second OTP, the first OTP will be invalid.
{% endhint %}

\
If you have not received your OTP after 10 minutes:

1. Check if your login email is keyed in correctly and you are looking at the right inbox.
2. Search for "One-Time Password (OTP) for PaySG".&#x20;
3. Check junk/spam boxes.&#x20;
4. Look at outlook rules/junk email filter as PaySG OTPs come from an internet source.&#x20;
5. Use other browsers and/or personal devices (e.g. mobile device).&#x20;
6. Check if colleagues are also experiencing this delay.&#x20;


# Costs

## What are the fees/charges incurred to onboard to PaySG?

There are no fees charged for using PaySG. However, you will need to account for Stripe's. Refer to our section on [Stripe onboarding](/overview/stripe-onboarding) for more information.


# Timeline

The following guide provides more information on the estimated duration for each phase of integrating your e-service with PaySG.

## How long will it take to onboard/integrate with PaySG?

{% hint style="warning" %}
The stakeholders and durations listed in the tables are **not prescriptive**. Stakeholders and durations differ between teams.
{% endhint %}

<table><thead><tr><th width="155">Phase</th><th width="160">Duration</th><th>Task</th><th>Stakeholder</th></tr></thead><tbody><tr><td>Budget approval</td><td>Based on your team</td><td>Seek clearance from your team/department head to budget for the transaction fees incurred by Stripe if necessary</td><td><ol><li>Your team</li><li>Team/department head who can approve budget requests</li></ol></td></tr><tr><td>Stripe set up</td><td>Based on your team</td><td>Follow the steps in our <a href="/pages/n6YnXMOkk4BYGFbx54A2">Stripe onboarding guide</a></td><td><ol><li>Your team</li><li>Procurement/finance team</li></ol></td></tr><tr><td>Testing in PaySG's staging environment</td><td>2-4 weeks, based on your implementation team</td><td>Complete testing in our staging environment to ensure that details and payment flows are working as expected</td><td>For dashboard-only users: Your team<br><br>For API users:<br>Your technical team/vendor</td></tr><tr><td>Testing in PaySG's production environment</td><td>2-4 weeks, based on your implementation team</td><td>Complete testing in our staging environment to ensure that details and payment flows are working as expected</td><td>For dashboard-only users: Your team<br><br>For API users:<br>Your technical team/vendor</td></tr><tr><td>Go live</td><td>Based on your team</td><td></td><td>For dashboard-only users: Your team<br><br>For API users:<br>Your technical team/vendor</td></tr></tbody></table>


# API keys

### How do I get an API key?

Contact us at [go.gov.sg/contact-paysg](https://go.gov.sg/contact-paysg) with a valid gov.sg email for an API key to be provisioned. Please ensure that the email address has been used to log in to [staging.pay.gov.sg](https://staging.pay.gov.sg) and [pay.gov.sg](https://pay.gov.sg) before. Note that the API key holder must be added as a Billing collaborator on the payment service.

### Why doesn't my API key work?

Ensure that the email address the API key was issued to is added as a Billing collaborator to the payment service.

### Do I need a new API key for each payment service?

No, API keys are associated with email addresses, not payment services. As long as the API key holder is added as a Billing collaborator on the relevant payment service, the API key can be used to create payments via API.

### Does the API key expire?

No, our API keys do not currently expire.

### What email address should I use for the API key?

We typically suggest teams to use a group email address (e.g. <agency-finance-team@agency.gov.sg>).

### What happens to the API key if the API key holder leaves the organisation?

The API key will still remain valid. However, we strongly suggest the team either use a group email for the API key, or ensure that a new API key is issued to someone within the organisation.


# API integration

This page includes FAQs from technical teams and vendors when integrating with PaySG.

## Payments and refunds

### Does the payment link get cancelled after the due date?

No, the due date is meant for display to payers and is **optional.**

Payment links are valid as long as (1) they aren't cancelled by someone from your agency and (2) payment has not been successful. Cancellations must be done manually.

### Does PaySG return payment status information to our e-service?

Yes. We have [webhooks](/webhooks/introduction)[ ](/webhooks/introduction)that you can use for real-time status updates.

### Is the payment page / payment email customisable?

No, the fields in the payment page and payment email are not customisable.

## Resources

### Do you provide code snippets for Java/Python etc.?

No, we do not provide code snippets. Please refer to our guide on [endpoints ](/start-an-api-integration/endpoints)and [API resources](/api-resources/events) for relevant information.

### Does PaySG have a refund API?

Yes, we have a refund API. Please refer to [Refund a payment](/api-resources/payments/refund-a-payment)f or more information.

## Integration

### What is the lead time for integrating with PaySG?

Please refer to our section on [timelines](/faq/timeline) for more information.

### Can I integrate my intranet application/e-service with PaySG?

No, PaySG requires internet access.

### Can PaySG interface with our agency's existing financial system (e.g. Workday)?

PaySG is not currently integrated with Workday by default. You may make use of our APIs should you wish to integrate our services with your services.

### Can PaySG interface with our vendor's system?

Please refer to our guide on our [endpoints](/start-an-api-integration/endpoints) to find out more about how your vendor can integrate with our APIs.

## Others

### How do I redirect users back to my agency's page?

Include a return\_url of choice when creating a new payment link.&#x20;


# Payments

### Can duplicate payments occur?

* Stripe does not allow duplicate payments.
* On our payment page, payers will no longer be able to make additional payment once the initial payment has been successful, as shown below.

<figure><img src="/files/CWe8Fdq3Xik8LyqVqc8j" alt="" width="326"><figcaption></figcaption></figure>

* If you are using bank PayNow and enabled access to the bank's refund function, repeated payments that occur during the validity of the PayNow QR code will automatically be refunded under the following conditions:
  * You have enabled and have agreements with the bank on refunds
  * The  bank integration supports refunds
* If your agency did not enable access to the bank's refund function, the duplicate payment will be marked as invalid in your payout report.

### **Are there any limitations on the number of payment services or payment links I can create?**

There are no specific limitations on the number of payment services or payment links you can create.&#x20;

### Is the PayNow QR code duration customisable?

No. Stripe's PayNow QR codes will refresh after an hour.

### What are the minimum and maximum payment amounts?

Card payments have a minimum amount of $0.01 and a maximum amount of $200,000.

Stripe PayNow payments have a minimum amount of $0.01 and a maximum amount of $200,000.

Do note that collecting small payment amounts could result in transaction fees exceeding the collected payment amount, leading to a negative Stripe account balance.

### **Can I use PaySG for recurring payments or subscription-based services?**

Recurring payments, known as subscriptions on PaySG, can currently only be collected via [payment forms.](/start-using-the-dashboard/payment-forms)

### **How long does it take for payments to arrive in my bank account?**

Stripe consolidates all transactions in a day and initiates a single deposit into your bank account three to seven business days later.

## Payment descriptors

### Can I customise the descriptor that will be reflected in payers' bank statements?

You can customise the descriptor on [Stripe's dashboard.](https://dashboard.stripe.com/settings/update/public/support-details)

### Can I customise the descriptor that will be reflected in my agency's bank statements?

You can contact Stripe directly to customise this.


# Payment methods

### **Can I customise the payment methods I want to offer?**

Yes, you have the flexibility to customize the payment methods you want to support. Simply go to your Stripe dashboard, navigate to Settings > Payment Methods. For more information on Stripe's available payment methods in Singapore, refer to their page [here](https://stripe.com/en-sg/pricing).

**Credit/debit cards**

To enable selected card payments, you will need to do the following:

1. In your Stripe dashboard, go to "Settings"
2. (For staging/UAT only) Toggle on "Test mode"
3. Go to "Payments"
4. Turn on/off the desired payment method

**Apple/Google Pay**

To enable payments via Apple or Google Pay, you will need to do the following:

1. In your Stripe dashboard, go to "Settings"
2. (For staging/UAT only) Toggle on "Test mode"
3. Go to "Payments"
4. Go to "Payment method domains"
5. Add staging.pay.gov.sg (for staging/UAT) or pay.gov.sg (for production)
6. Inform the PaySG team so that the relevant payment methods can be activated

### I enabled/disabled a payment method on Stripe, but it isn't updated on the PaySG payment page. How do I troubleshoot this?

* Head to Stripe's [payment method settings](https://dashboard.stripe.com/settings/payment_methods).
* Ensure that the payment method was enabled/disabled under **PaySG configurations**.
* On PaySG, create a new payment link to verify that the payment method was correctly enabled/disabled. Do note that newly enabled/disabled payment methods will only apply to subsequently created payment links and not existing payment links.

<figure><img src="/files/dihzLm5OJsEy2VH74r5T" alt=""><figcaption></figcaption></figure>

### I want to offer a payment method but I can't find it on Stripe's settings page. How do I proceed?

Please refer to Stripe's page [here](https://stripe.com/en-sg/pricing) to find out more about it's available payment methods in Singapore.


# Payouts and transaction fees

### What are Stripe's transaction fees?

You may refer to the bulk tender GVT (T) 24010 for Stripe's transaction fees.

### How are transaction fees paid?

Stripe deducts transaction fees from the payout before depositing it to your agency's bank account.

### Can I pay transaction fees separately instead of having it deducted from my payout?

No, Stripe uses net settlement and only deposits the payout upon transaction fee deduction.

### Can I customise the descriptor that will be reflected in payers' bank statements?

Yes, you can customise the descriptor on [Stripe's dashboard.](https://dashboard.stripe.com/settings/update/public/support-details)

### Can I customise the descriptor that will be reflected in my agency's bank statements?

You can contact Stripe directly to customise this.


# Refunds

### Why can't I initiate a refund?

Refunds can only be initiated within 90 days of the initial payment.

### **How do I initiate refunds for successful payments?**

Refunds can be initiated through our [dashboard](/start-using-the-dashboard/payments-and-refunds/refunds) or via [API](/api-resources/payments/refund-a-payment).&#x20;

### **How long does it take to receive refunds?**

**For payments collected via Stripe's payment methods**

Once refunds are initiated, PaySG immediately forwards the request to Stripe, which submits the refund requests to the payer's bank or card issuer. The payer sees the refund approximately 5 - 10 business days later, depending on the bank or card issuer.

**For payments collected via bank PayNow**

Refunds are credited back into the payer's account in real-time.

### Can refunds be credited to a different bank account/card from the initial paying bank account/card?

No. Refunds will be processed via the payment method that the payment was made by.

### Can PaySG handle refunds for payments that were not collected on PaySG?

No, we only process refunds for payments collected via PaySG.

### Are there any charges/fees for refunds?

No, there are no additional transaction fees incurred for refunds.&#x20;

### Does PaySG have a refund API?

Yes, we have a [refund API](/api-resources/payments/refund-a-payment) available.

### Does PaySG support multiple partial refunds?

Yes, we support partial refunds. You may initiate multiple refunds within the remaining refundable amount. Refunds will be processed one at a time.

### Which PayNow payments will automatically be refunded by PaySG?

{% hint style="warning" %}
This is only applicable to agencies with direct bank integration for PayNow, not Stripe PayNow.&#x20;
{% endhint %}

Only the first successful payment that includes (1) the correct reference ID and (2) correct payment amount will be recognised and marked as "paid".

The following payments will be automatically refunded:&#x20;

* Payments made with a correct reference ID that matches an expected unpaid payment in PaySG, with an incorrect payment amount.&#x20;
* Payments made with a correct reference ID that matches an expected payment in PaySG, but the payment has already been made (i.e. a duplicate payment).


# Security and compliance

## Stripe

### **How secure is Stripe as a payment provider?**

Stripe is governed by the Payment Services Act and regulations of the Monetary Authority of Singapore (MAS). It adheres to the highest level of compliance in the payment industry, including PCI DSS v3.2.1 certification.

### **What fraud detection measures are in place through Stripe's Radar?**

Stripe's Radar is an advanced fraud protection engine that utilizes machine learning algorithms to detect and prevent fraudulent activities. It analyzes various signals such as user behavior, location, historical card data, and financial partner data to identify potential fraud.

### **What is 3D Secure and how does it protect against fraud?**

3D Secure is a fraud protection method provided by card networks. It adds an additional layer of security during online transactions by verifying the cardholder's identity. The need for 3D Secure is determined by the issuing bank of the customer's card.

### **Is PaySG compliant with the Payment Services Act and MAS regulations?**

Yes, PaySG is compliant with the Payment Services Act and the regulations set by the Monetary Authority of Singapore (MAS).


# Downtime and maintenance

## Does PaySG have scheduled maintenance periods?

No, PaySG itself does not have scheduled maintenance.&#x20;

In the event that Stripe or banks inform us of upcoming scheduled maintenance, we will inform agencies accordingly. You can also monitor our status at [status.pay.gov.sg](https://status.pay.gov.sg), and Stripe's status at [status.stripe.com](https://status.stripe.com/).

## What happens if PaySG or its underlying services have unexpected downtime?

A banner will be displayed on our dashboard and payment page to inform users of the disruption, as shown below. Agencies will also be notified via email. You can also monitor our status at [status.pay.gov.sg](https://status.pay.gov.sg), and Stripe's status at [status.stripe.com](https://status.stripe.com/).

<figure><img src="/files/t5SqzOGomDRcum0VHlKe" alt=""><figcaption><p>Dashboard downtime banner</p></figcaption></figure>


