Testing your Stripe integration can be challenging, especially when balancing secure environments with the risks of exposing sensitive information. Stripe sandboxes offer a solution by allowing developers to set up multiple separate testing areas that mimic real-world situations without affecting live transactions. Connecting Stripe sandboxes to GitHub automates the testing process, making development smoother, and reducing the test tangles previously encountered by having only a single test mode for each Stripe account.
This blog post examines the importance of using these Sandboxes and outlines methods for managing sandbox API keys securely, ensuring that your payment integration works effectively and protects user data. All the code samples featured in this post are available in this GitHub repository.
A Simple Sandbox Integration Example
Stripe uses the API keys linked to a sandbox to authenticate API requests directed at the corresponding sandbox environment. If a request is made without a key, an invalid request error is returned; conversely, an authentication error is raised if the key is incorrect or outdated.
If you don't have a Stripe account yet, sign up and register a Stripe account, and create your first Sandbox.The following steps show you how to find your Sandbox key,:
The following steps show you how to find a sandbox key:
-
To view a complete list of all the Sandboxes in your account, visit https://dashboard.stripe.com/sandboxes or choose the account drop down from the top left corner of the dashboard:
-
Choose the sandbox you want to access programmatically, and then choose the Developer button at top right corner, and API keys.
-
From the API Keys dashboard you can reveal, revoke, and create API keys. Check the documentation to learn how to manage API keys. To see the API key for your Sandbox environment, choose Reveal test key:
API keys include both a publishable and secret key. The publishable key can be viewed in public and cannot be compromised. The secret API key is used to authenticate requests on your server when interacting with the Sandbox. By default, you can use the secret key to perform any API request without restriction. To avoid accidentally making an API call to the wrong sandbox, account, or having your secret API key compromised, ensure that it is stored securely in your web or mobile app’s server-side code (such as in an environment variable or credential management system) to call Stripe APIs. Don’t expose this key on a website or embed it in a mobile application.
The following steps show how to save this key as an environment variable in a server side Node.js application using the Express framework:
Step 1: Set Up the Environment
Install Dependencies: Ensure you have Node.js and npm installed. Then create a new project folder and run the following commands to initialize a new Node.js project and install the required dependencies:
mkdir stripe-sandbox-example cd stripe-sandbox-example npm init -y npm install express stripe dotenv
- Create an Environment Variable: Create a .env file in the root of your project and add your Stripe Sandbox API key there:
STRIPE_API_KEY=sk_test_key
Step 2: Create the Express Application
Create a file named app.js in your project folder, and add the following code:
// app.js require('dotenv').config(); // Load environment variables from .env file const express = require('express'); const Stripe = require('stripe'); const app = express(); const port = process.env.PORT || 3000; // Initialize Stripe with the Sandbox API key from the environment variable const stripe = Stripe(process.env.STRIPE_API_KEY); // Middleware to parse JSON requests app.use(express.json()); // Example route to create a payment intent app.post('/create-payment-intent', async (req, res) => { const { amount, currency } = req.body; try { const paymentIntent = await stripe.paymentIntents.create({ amount: amount, currency: currency, }); res.status(200).json({ clientSecret: paymentIntent.client_secret }); } catch (error) { console.error('Error creating payment intent:', error); res.status(500).json({ error: error.message }); } }) // used later for testing connections app.get('/account', async (req, res) => { try { const account = await stripe.accounts.retrieve(); res.status(200).json(account); } catch (error) { console.error('Error retrieving account:', error); res.status(500).json({ error: error.message }); } }); // Start the server app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); });
Step 3: Run the Application
Start your Express Server: Run the following command in your terminal to start the server:
> node app.js
Access the `/create-payment-intent` endpoint by sending a POST request. Use a tool like Postman or curl. The following example uses curl:
curl -X POST http://localhost:3000/create-payment-intent \ -H "Content-Type: application/json" \ -d '{"amount": 1000, "currency": "usd"}'
In your Stripe dashboard, first ensure that you are in the correct sandbox, and then open Stripe Workbench to see the results of the request:
Integrating Sandbox deployments with Github
Integrating Stripe Sandboxes into your version control system’s deployment workflow is essential for managing testing environments efficiently and securely. For example, using GitHub’s capabilities alongside Stripe Sandboxes, you can simplify and secure your deployment processes, increase collaboration among team members, and maintain tight control over sensitive configurations. Here’s how to manage this integration.
Step 1: Ensure GitHub is ignoring sensitive files
A well-configured .gitignore configuration file is important to prevent accidentally uploading sensitive files like .env. The previous Node.js example sets the sandbox API key as an environment variable using a .env file. To ensure this file is never committed to GitHub, the following script is included in the .gitignore file. This is the first file to be committed to the repository:
# dotenv environment variable files .env .env.development.local .env.test.local .env.production.local .env.local
This .gitignore
configuration varies according to the runtime and framework you are working with.
Step 2: Set Up GitHub Secrets
When using GitHub Actions for CI/CD, manage sensitive data securely using GitHub Secrets:
- Go to your GitHub repository. Choose Settings from the toolbar. On the left sidebar, navigate to Secrets and variables and choose Actions then choose New repository secret.
- Add your secrets one at a time:
Step 4: Reference Secrets in GitHub Actions
GitHub Actions allows you to automate your workflows and CI/CD processes. Start by creating a workflow that incorporates your Sandbox environment for testing. In your GitHub Actions workflow file (usually located in .github/workflows/ci.yml
), reference the secrets you added.
The following workflow automates the process of testing the application whenever changes are pushed to the main branch. It checks out the latest code, sets up the necessary environment, installs any required dependencies, and runs tests that interact with Stripe to verify that the code is executing in the correct sandbox. This helps ensure the integrity and functionality of the application in a continuous and efficient manner, while maintaining secure practices in handling sensitive credentials like API keys:
name: CI/CD with Stripe Sandboxes on: push: branches: - main jobs: devSandbox: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '18' - name: Install Dependencies run: npm install - name: Run Tests Using Sandbox env: STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }} run: npm run test # Ensure tests use correct Sandbox API
Step 4. Creating a test file
The test script defined in app.test.js
is designed to validate the integration of the application with Stripe's Sandbox environment. It uses the supertest library to send HTTP requests to the Express application imported from app.js
.
To set up tests for your Node.js application using Jest and supertest, follow these steps:
- Install Jest for running tests and supertest for making HTTP requests in your test suite by running the following command:
npm install --save-dev jest supertest
- Modify your package.json file to include a test script that runs jest. Add the following line in the "scripts" section:
{ "scripts": { "test": "jest" } }
- Create a test file named app.test.js in your project root or a designated tests folder. In this file, write the test suite using Jest and supertest.
The test suite begins by verifying that the environment variable STRIPE_API_KEY
is set, ensuring that the application has the necessary credentials to interact with the Stripe API.
// __tests__/app.test.js const request = require('supertest'); // For making HTTP requests in tests const app = require('../app'); // Adjust the path as necessary require('dotenv').config(); // Load environment variables describe('Stripe Sandbox Integration', () => { beforeAll(() => { // Ensure the environment variables are set expect(process.env.STRIPE_API_KEY).toBeDefined(); }); // New test: Verify GET request to Stripe account test('GET /account should return the correct sandbox name', async () => { const response = await request(app).get('/account'); expect(response.status).toBe(200); expect(response.body).toHaveProperty('id'); // Check for the existence of an account ID expect(response.body.business_profile).toHaveProperty('name', 'Sandbox'); // Confirm business profile name expect(response.body.settings.dashboard).toHaveProperty('display_name', 'dev-sandbox'); // Check for display_name // Output the name of the sandbox console.log('Sandbox Name:', response.body.settings.dashboard.display_name); }); });
The script then verifies the connection to the Stripe API by making a GET request to the /account
endpoint of the Node.js Express application. This route is designed to fetch the account details from Stripe. Upon receiving the response, the test asserts that the status is 200, indicating a successful request, and checks that the response body contains the correct ‘dashboard.display_name property’ of ‘dev-sandbox’, confirming that the connection to the Stripe sandbox is correctly established and functioning as expected. This approach not only validates the API integration but also ensures that sensitive configurations are correctly set.
Now each time a new commit is made to the main branch, this workflow runs and verifies the application is configured for the correct sandbox environment.
This is the successful result of a recent commit:
Here are the corresponding logs in the associated Stripe sandbox:
Conclusion
Using Stripe Sandboxes helps to reduce the test tangles previously encountered by having only a single test mode for each Stripe account. Setting up individual sandboxes for testing allows for focused validation of features, minimizing the risk of affecting live operations. Connecting these environments with GitHub automates the testing process and leads to quicker updates.
Securing your sandbox API keys is equally important. Utilize environment variables or managed key services whenever possible to safeguard sensitive information. This approach not only improves the reliability of your integration but also builds confidence in your payment solutions. Learning how to work with Stripe Sandboxes helps you deliver dependable payment solutions that are easier to and free from interference by others.
Explore the sample GitHub repository to access all the code samples featured in this post and enhance your Stripe integration experience.
To learn more about developing applications with Stripe, visit our YouTube Channel.