Testing Your Integration#
Before you go live, test your partner integration in the GoCardless sandbox environment. Sandbox works like the live environment, but no real money moves and you can trigger events that your integration must be able to handle, but that are not easily reproducible in live production.
This page acts as a guide for testing:
- The OAuth flow that connects a merchant to your app
- Webhook handling for the events in Webhooks for Partners
- Importing mandates from outside your partner integration
In addition to the above, you should also be independently validating that all data is being displayed correctly in your partner app and that merchants are able to complete all the actions outlined in the Integration Guide.
Test accounts#
A partner integration involves two kinds of organisations, and you need both to test it end to end:
| Account | What it represents | How you use it |
|---|---|---|
| Partner account | Your organisation. This organisation owns your partner app integration. | You create your app in this account, set your redirect and webhook URLs, and view the Partner Dashboard. |
| Merchant account | One of your users. This account is connected to your app via the OAuth flow. | Go through the OAuth flow, create mandates and payments, trigger events that are handled by your partner integration |
This guide assumes you have created your partner app in a sandbox account. If you do not have access to a sandbox account with a live app, please see Partner Integrations - Before you start.
Create a merchant test account#
Create a second sandbox account with a different email address to your partner account. For testing, this will act as your merchant.
Test the OAuth flow#
As part of your integration you should have built a way to generate links to the OAuth flow using your app's client_id, client_secret and redirect_uri.
1. Connect your merchant test account#
Go through the OAuth flow via your app and sign in as your merchant test account. This should connect your merchant account to your app.
2. Check what your integration stores#
Verify that you are retrieving and storing the app access token from this connection, along with the GoCardless organisation ID of the connected merchant in your system.
3. Test each connection scenario#
| Scenario | How to test | Expected result |
|---|---|---|
| New merchant signs up | Clear your cache and fill in the sign up form instead of signing in with an existing account. | Successful connection. Your integration should complete the code exchange and store the access token and organisation ID. |
| Merchant declines | Go through the sign in/sign up flow and cancel on the authorisation screen. | GoCardless redirects with error=access_denied and an error_description. Your integration should show the merchant a clear message. |
| Merchant already connected | Run the flow again for a merchant you've already connected. | Your integration code exchanges for a new access token, and GoCardless disables the old one. Your integration should replace the old token. |
| Merchant revokes access | Revoke your app in the merchant's dashboard. | Your integration receives and processes a disconnection webhook. Your integration should mark the token stored against the merchant as revoked and should not attempt to make any more requests to the GoCardless API using it. |
If any of these scenarios produce unexpected results, refer back to Connect your merchants.
Test webhook handling#
Your partner integration should be set up to appropriately handle the events listed in Webhooks for Partners.
The following steps walk you through how to trigger these events from the sandbox environment.
1. Choose how to trigger events#
There are three ways to trigger events in the sandbox environment:
| Method | Use it for |
|---|---|
| GoCardless CLI. | Forwarding webhooks to a local instance of your partner integration. Creating/transitioning mandates, payments and billing requests to desired states. |
| Scenario simulators, through the API or dashboard | Transitioning a mandate, payment, refund, payout or billing request to a new state. |
| Send test webhook | Simulating events that have no simulator or trigger via the CLI. You choose the resource type, action and cause, and GoCardless sends the webhook to your endpoint. |
For testing against a local instance of your partner integration, the GoCardless CLI is recommended as it allows you to forward webhooks to your local handler, and will print logs of all generated events.
2. Trigger events#
Use the methods from the previous step to trigger the events your integration handles. See Key events for a list of events and their suggested handling.
Trigger events with the GoCardless CLI#
-
Install the GoCardless CLI
-
Log in using your merchant test account
-
Listen for webhooks. If running your integration locally, forward webhooks to your local instance.
You can then use the CLI to trigger events which your integration should handle appropriately.
The GoCardless CLI can create resources or transition existing resources. Run gocardless trigger --help for a full list of supported actions.
See Testing webhooks (CLI) for more information.
Trigger events with the scenario simulator#
You can use the dashboard or API triggered scenario simulator to transition resources in your merchant test account. The events from these transitions will be sent to your app's webhook URL for processing.
For more information see Scenario Simulator
Trigger events with Send test webhook#
For events that are not covered by the GC CLI triggers or the scenario simulator (e.g. payment.chargeback_cancelled), you can send test webhooks directly to your integration via the dashboard Send test webhook feature.
3. Test routing and reliability#
Run these checks as well as the individual events to verify the security and reliability of your integration:
| Check | How to test | Expected result |
|---|---|---|
| Routing to the merchant | Connect two merchant accounts and trigger the same event on each. | Each event is handled for the merchant in links.organisation. |
| Invalid signature | Send a request to your endpoint with a wrong Webhook-Signature header. | You reject the request and don't process any events in it. |
| Duplicate events | Resend an event from the dashboard. | You skip the event ID you've already processed. |
| Several events together | Trigger a simulator that creates more than one event, such as payment_paid_out. | You process every event in the webhook. |
Test mandate imports#
Merchants who already use GoCardless have mandates that exist before they connect to your app. Your integration should be able to find these mandates after the OAuth connection, match them to customers in your product, and store the mandate links. See Supporting mandates set up outside of your product for how to build this.
To test it, you need mandates to exist in the merchant test account before you connect it to your app. The steps below follow that order.
1. Use a merchant account that isn't connected#
The import flow runs when a merchant connects, so you need a merchant test account with no connection to your app. Do one of the following:
- Create a new merchant test account, as described in Create a merchant test account.
- Revoke your app in the dashboard of a merchant account you've already connected. Your integration should handle the disconnection webhook.
2. Create mandates in the merchant account#
Create mandates using the GoCardless CLI or the scenario simulator. Create enough mandates to cover each case your import handles:
| Case to cover | How to set it up | Expected result in your integration |
|---|---|---|
| Exact email match | Give the GoCardless customer the same email as a customer in your test data. | The mandate is auto-matched. |
| Metadata match | Add a partner_id to the GoCardless customer's metadata that matches a customer ID in your test data. | The mandate is auto-matched. |
| Probable match | Use a customer with a similar name and the same postal code as a customer in your test data, but a different email. | The mandate is shown as a probable match for the merchant to review. |
| Unresolved | Use a customer who doesn't match anyone in your test data. | The mandate is shown as unresolved, and the merchant can pair it manually or skip it. |
| Mandates that can't be used to collect payments | Move a mandate to failed, cancelled or expired, for example with the mandate_failed and mandate_expired simulators. | The mandate isn't included in the sync. |
Create mandates with the GoCardless CLI#
-
Log in to the CLI using the merchant test account.
-
Create a customer with the details you want your integration to match on:
-
Trigger a mandate for that customer. The CLI creates the bank account and mandate, and activates the mandate:
Replace
CU123with the customer ID from the previous step. -
Repeat for each case in the table. To create a mandate with an auto-generated customer, run
gocardless trigger mandate_activatedwith no arguments.
To create a mandate in a different state, use another trigger such as mandate_failed, mandate_expired or mandate_pending_submission. Run gocardless trigger --help for the full list. See the CLI reference for details.
Create mandates with the scenario simulator#
-
Create a customer, bank account and mandate in the merchant test account, using the dashboard or the API. A new mandate starts in
pending_submission. -
Use the scenario simulator to move the mandate to the state you want to test. For example, run the
mandate_activatedsimulator against the mandate ID, from the dashboard or the API.
3. Connect the merchant account to your app#
Before you connect, confirm the mandates exist by running gocardless list mandates or checking the sandbox dashboard.
Go through the OAuth flow from your app and sign in as the merchant test account.
4. Sync the mandates in your app#
In your app, start the sync, for example by selecting Sync Existing Mandates. Then check the following:
| Check | Expected result |
|---|---|
| Mandates are retrieved | Your integration lists the merchant's mandates and customers using the merchant's access token, and joins them on mandates[].links.customer. |
| Matching | Each mandate you created ends up in the match tier you expected: auto-matched, probable match, or unresolved. |
| Review and confirmation | The merchant can confirm, reassign, manually pair or skip mandates. Nothing is linked until they confirm. |
| Mandate links are stored | After confirmation, you store the GoCardless mandate ID against the matched customer, and the mandate is available for collecting payments. |
| Collecting a payment | You can create a payment against an imported mandate. Use the payment_paid_out simulator to check that your integration handles the resulting webhooks. |
If any of these produce unexpected results, refer back to Supporting mandates set up outside of your product.