Test Environment
A separate PayNow environment, running the same code as production, for developers testing integrations away from real stores.
The test environment runs the same release as production, so everything works the way it does on your live store. Its data is completely separate - none of your live stores, products, customers or orders are in it, and nothing you do there reaches production.
| Service | Test environment | Production |
|---|---|---|
| Dashboard | https://dashboard.canary.pn-builds.xyz | https://dashboard.paynow.gg |
| API | https://api.canary.pn-builds.xyz | https://api.paynow.gg |
| Checkout | https://checkout.canary.pn-builds.xyz | https://checkout.paynow.gg |
Point your integration at the test environment's API base URL instead of production. Everything else, including paths and authentication, is the same.
Using the TypeScript SDK
The TypeScript SDK talks to production by default. Pass baseUrl when you create a client to send its requests to the test environment instead:
import { createManagementClient, createStorefrontClient } from "@paynow-gg/typescript-sdk";
const baseUrl = "https://api.canary.pn-builds.xyz";
const management = createManagementClient({
baseUrl,
apiKey: process.env.PAYNOW_API_KEY!,
storeId: "411486491630370816",
});
const storefront = createStorefrontClient({
baseUrl,
storeId: "411486491630370816",
});The API key and store ID must come from the test environment's dashboard. Keys and stores from production don't exist there.
Read the base URL from an environment variable so the same code can switch between environments without changes:
const management = createManagementClient({
baseUrl: process.env.PAYNOW_API_BASE_URL, // unset in production
apiKey: process.env.PAYNOW_API_KEY!,
storeId: process.env.PAYNOW_STORE_ID!,
});Leaving baseUrl unset falls back to https://api.paynow.gg.
Using PayNow.js
PayNow.js opens the production checkout by default. Pass baseURL to checkout.open to open the test environment's checkout instead:
import PayNowJS from "@paynow-gg/paynow.js";
PayNowJS.checkout.open({
token: "checkout token",
baseURL: "https://checkout.canary.pn-builds.xyz",
});The checkout token must come from the test environment's API. A token from production won't open there, and a test token won't open on production's checkout. Leave off the trailing slash, as PayNow.js adds its own.
What it's for
Developers testing integrations they don't want running against real stores. API clients, headless storefronts, webhook handlers and the like. It isn't a place to run or rehearse a real store. No real payments can be processed here.
Getting started
Because the data is separate, you start from scratch. Set up a store in the test environment just as you would on production, following Creating a Store and Your First Product. Recreate whatever you want to test there.
Paying in the test environment
Payments run in test mode. No real money moves and real cards are declined, so checkout only accepts the test cards below. For every card, use any future expiry date, any three-digit CVC (four digits for American Express), and anything for the name and postal code.
Orders paid this way behave like real orders inside the test environment. They show in Content → Orders, count towards analytics, and can be refunded, but they never reach your live store, your balance or your payouts.
Successful payments
| Card | Number |
|---|---|
| Visa | 4242 4242 4242 4242 |
| Visa (debit) | 4000 0566 5566 5556 |
| Mastercard | 5555 5555 5555 4444 |
| Mastercard (prepaid) | 5105 1051 0510 5100 |
| American Express | 3782 822463 10005 |
| Discover | 6011 1111 1111 1117 |
Declined payments
Each of these cards is declined at checkout with a specific reason, so you can test how your integration handles a failed payment.
| Scenario | Number |
|---|---|
| Generic decline | 4000 0000 0000 0002 |
| Insufficient funds | 4000 0000 0000 9995 |
| Lost card | 4000 0000 0000 9987 |
| Stolen card | 4000 0000 0000 9979 |
| Expired card | 4000 0000 0000 0069 |
| Incorrect CVC | 4000 0000 0000 0127 |
| Processing error | 4000 0000 0000 0119 |
| Incorrect card number | 4242 4242 4242 4241 |
| Too many attempts | 4000 0000 0000 6975 |
Fraud checks
These cards trigger fraud screening. Whether a flagged payment is blocked depends on the risk level.
| Scenario | Number | Result |
|---|---|---|
| Always blocked | 4100 0000 0000 0019 | Blocked as highest risk |
| Highest risk | 4000 0000 0000 4954 | Flagged as highest risk, may be blocked |
| Elevated risk | 4000 0000 0000 9235 | Flagged as elevated risk, may be blocked |
| CVC check fails | 4000 0000 0000 0101 | CVC check fails, may be blocked |
| Postal code check fails | 4000 0000 0000 0036 | Postal code check fails, may be blocked |
Chargebacks
These cards pay successfully, then a chargeback (dispute) is opened against the order shortly afterwards. Use them to test your chargeback webhooks and how your store handles a disputed order.
| Scenario | Number | Result |
|---|---|---|
| Fraudulent | 4000 0000 0000 0259 | Disputed as fraudulent |
| Product not received | 4000 0000 0000 2685 | Disputed as product not received |
| Inquiry | 4000 0000 0000 1976 | Opened as an inquiry |
| Early fraud warning | 4000 0000 0000 5423 | Receives an early fraud warning instead of a full dispute |
| Multiple chargebacks | 4000 0004 0400 0079 | Disputed more than once |
3D Secure
| Scenario | Number | Result |
|---|---|---|
| Authentication required | 4000 0000 0000 3220 | Succeeds once the 3D Secure challenge is completed |
| Authenticated, then declined | 4000 0084 0000 1629 | Declined after the challenge is completed |
| Authentication error | 4000 0084 0000 1280 | The 3D Secure check fails and the payment is declined |
On the 3D Secure test challenge, choose to complete the authentication to let it succeed, or fail it to test a failed authentication.
Nothing moves to production
The test environment has its own database, messaging, search and analytics. Nothing flows from it into production, and there is no way to export or transfer anything across: products you create, settings you change and orders you place in the test environment cannot be moved into your live store.
Set it up again for real. Once your integration works in the test environment, point it at production and recreate the store, products and keys it needs there. Nothing is promoted across.