Stripe Payment Gateway Integration using PHP

There are many payment services available in the market to integrate payment gateway in an application. For example, PayPal, Stripe, Sage Pay, CCAvenue and there is a long list out there. They provide API for integrating payment gateway to our software. In many countries, Stripe is the widely used for the transactions with credit and debit cards. By using a payment gateway services / API, we can enable users to do financial transactions with our application. When it comes to integrating a payment gateway with our application, we need to choose a reputed provider. Because it gives trust to the users and it is important as it involves real money.

Stripe Payment Gateway Integration using PHP

In this article, we are going to see about implementing Stripe payment gateway and how to integrate using PHP. In a previous tutorial, we have seen an example of integrating PayPal payment gateway with PHP. By referring to this linked article, you can easily get the idea about the payment flow.

1. Create a Stripe account Stripe account and get API keys

Create a Stripe account and login to the dashboard. Navigate through the Developers -> API keys menu to get the API keys. There is two type of standard API keys named secret key and publishable key. The secret key will be masked by default which has to be revealed by clicking reveal key token control explicitly.

Stripe-Payment-Gateway-API-Key

These keys are stored in a config file as PHP constants and will be used in the Stripe payment code later.

2. HTML Stripe Payment Form

In this HTML form, it includes fields like cardholder name, card number, CVC, expiration month/year to get the user input. We have already created this form with such fields for the credit card validator example. It also includes the item_number, item_name, amount and currency_code as the hidden input. 

Stripe API recommends using tokens instead of submitting test card details while testing the Payment integration. The test tokens are mapped with the tokenized card details by using Stripe JavaScript library.

 

3. Client-Side Card Validation and Response Handler with Stripe JavaScript Library

On submitting the card details, the entered data will be validated in the client side. Once the validation returns true, then the card details will be sent to the get Stripe server to get a token. The Stripe API will return the token and it will be added to the payment form fields using Stripe ResponseHandler. This is the most welcoming feature of the Stripe payment handling card details and validation with Stripe server via JavaScript.   

After inserting the token, the form will be submitted programmatically using the Javascript. While implementing Sage Pay payment integration, we have seen how to send the payment request using JavaScript.


 

4. Process Charges via Stripe in PHP

Download Stripe PHP library which is required for processing charges using PHP code. The payment related functions are created in a PHP class StripePayment.php. It processes the Stripe charges by sending the API token and other payment request data like customer id, amount, currency and more. After processing the payment request the Stripe API will return the payment response as a JSON object.  

5. Store and Display Stripe Payment Response

The serialized JSON object is parsed to get the payment status and response. The details like email, item_number, item_name, payment status and response are stored in the tbl_payment table by using the MySQL insert. I used the prepared statement with MySQLi for handling the database operations. 

Payment Database Structure

 The following SQL script shows the query statement for creating the payment database table to store the payment data returned by the Stripe API after processing our payment request.

--
-- Table structure for table `tbl_payment`
--

CREATE TABLE `tbl_payment` (
  `id` int(11) NOT NULL,
  `email` varchar(255) NOT NULL,
  `item_number` varchar(255) NOT NULL,
  `amount` double(10,2) NOT NULL,
  `currency_code` varchar(55) NOT NULL,
  `txn_id` varchar(255) NOT NULL,
  `payment_status` varchar(255) NOT NULL,
  `payment_response` text NOT NULL,
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for table `tbl_payment`
--
ALTER TABLE `tbl_payment`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `tbl_payment`
--
ALTER TABLE `tbl_payment`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;

Testing with Stripe Payment Gateway Demo

In this article, I have added a demo by showing this payment form with test card numbers. You can find more test data in the Stripe API testing documentation. You can use the test card numbers to demonstrate Stripe payment integration. 

Note: Before going to live, we need to test Stripe payment in test data mode. Once we found everything is working good with the test mode, then it will be easy to go live by toggling the data mode. 

Stripe Payment Form Screenshot

This screenshot shows the fields required to be in the Stripe payment form to get data from the user for processing payment.

Stripe_payment_form_screenshot

Basic test card numbers

Genuine card information cannot be used in test mode. Instead, use any of the following test card numbers, a valid expiration date in the future, and any random CVC number, to create a successful payment.

Card numbers Tokens PaymentMethods

NUMBER BRAND CVC DATE
4242424242424242 Visa Any 3 digits Any future date
4000056655665556 Visa (debit) Any 3 digits Any future date
5555555555554444 Mastercard Any 3 digits Any future date
2223003122003222 Mastercard (2-series) Any 3 digits Any future date
5200828282828210 Mastercard (debit) Any 3 digits Any future date
5105105105105100 Mastercard (prepaid) Any 3 digits Any future date
378282246310005 American Express Any 4 digits Any future date
371449635398431 American Express Any 4 digits Any future date
6011111111111117 Discover Any 3 digits Any future date
6011000990139424 Discover Any 3 digits Any future date
3056930009020004 Diners Club Any 3 digits Any future date
36227206271667 Diners Club (14 digit card) Any 3 digits Any future date
3566002020360505 JCB Any 3 digits Any future date
6200000000000005 UnionPay Any 3 digits Any future date

Each test card's billing country is set to U.S. If you need to create test card payments using cards for other billing countries, use our international test cards.

We recommend using our test IDs when testing your integration and creating charges, instead of passing card information directly to the API. Using these test IDs in place of card numbers helps ensure your production integration is developed in a PCI compliant manner and is not going to handle card information directly. Each test ID is human-readable and represents card information that has been tokenized with our client-side libraries (e.g., Stripe Elements, Stripe.js).

International test card numbers

You can use any of the following test cards to simulate a successful payment for different billing countries.

Americas Europe, Middle East, and Africa Asia-Pacific

NUMBER TOKEN PAYMENT METHOD COUNTRY BRAND
4000000760000002 tok_br pm_card_br Brazil (BR) Visa
4000001240000000 tok_ca pm_card_ca Canada (CA) Visa
4000004840008001 tok_mx pm_card_mx Mexico (MX) Visa

Regulatory (3D Secure) test card numbers

The following card information tests payments affected by regional regulations such as Strong Customer Authentication (SCA). Use it to test saving cards with the Setup Intents API.

Card numbers PaymentMethods

NUMBER DESCRIPTION
4000002500003155 This card requires authentication for one-time payments. However, if you set up this card and use the saved card for subsequent off-session payments, no further authentication is needed. In live mode, Stripe dynamically determines when a particular transaction requires authentication due to regional regulations such as Strong Customer Authentication.
4000002760003184 This card requires authentication on all transactions, regardless of how the card is set up.
4000008260003178 This card requires authentication for one-time payments. All payments will be declined with an insufficient_funds failure code even after being successfully authenticated or previously set up.
4000003800000446 This card requires authentication for one-time and other on-session payments. However, all off-session payments will succeed as if the card has been previously set up.
4000003560000016 This card requires authentication on all transactions, regardless of how you set it up. You can only use this card for INR payments.
4000053560000011 This card requires authentication on all transactions, regardless of how you set it up. You can only use this card for INR payments.
5000503560018071 This card requires authentication on all transactions, regardless of how you set it up. You can only use this card for INR payments.
5000553560018126 This card requires authentication on all transactions, regardless of how you set it up. You can only use this card for INR payments.
374433407674077 This card requires authentication on all transactions, regardless of how you set it up. You can only use this card for INR payments.
5000503560018097 This card requires authentication for one-time payments. However, if you set up this card and use the saved card for subsequent off-session payments, no further authentication is needed. You can only use this card for INR payments.
4000003560000057 This card requires authentication for one-time payments. However, if you set up this card and use the saved card for subsequent off-session payments, no further authentication is needed. You can only use this card for INR payments.

3D Secure test card numbers and tokens

Not all cards support 3D Secure or require the customer be redirected to their card issuer's authentication page. Use the following card information to test 3D Secure payments.

Card numbers Tokens PaymentMethods

NUMBER 3D SECURE USAGE DESCRIPTION
4000000000003220 Required 3D Secure 2 authentication must be completed for the payment to be successful. By default, your Radar rules will request 3D Secure authentication for this card.
4000000000003063 Required 3D Secure authentication must be completed for the payment to be successful. By default, your Radar rules will request 3D Secure authentication for this card.
4000008400001629 Required 3D Secure authentication is required, but payments will be declined with a card_declined failure code after authentication. By default, your Radar rules will request 3D Secure authentication for this card.
4000008400001280 Required 3D Secure authentication is required, but the 3D Secure lookup request will fail with a processing error. Payments will be declined with a card_declined failure code. By default, your Radar rules will request 3D Secure authentication for this card.
4000000000003055 Supported 3D Secure authentication may still be performed, but is not required. By default, your Radar rules will not request 3D Secure authentication for this card.
4000000000003097 Supported 3D Secure authentication may still be performed, but is not required. However, attempts to perform 3D Secure result in a processing error. By default, your Radar rules will not request 3D Secure authentication for this card.
4242424242424242 Supported 3D Secure is supported for this card, but this card is not enrolled in 3D Secure. This means that if 3D Secure is requested by your Radar rules, the customer will not go through additional authentication. By default, your Radar rules will not request 3D Secure authentication for this card.
378282246310005 Not supported 3D Secure is not supported on this card and cannot be invoked. The PaymentIntent will proceed without performing authentication.

All other Visa and Mastercard test cards do not require authentication from the customer's card issuer.

Testing for specific responses and errors

The following test cards can be used to create payments that produce specific responses—useful for testing different scenarios and error codes. Verification checks only run when the required information is provided (e.g., for cvc_check to be set to fail, a CVC code must be provided).

Card numbers Tokens PaymentMethods

NUMBER DESCRIPTION
4000000000000077 Charge succeeds and funds will be added directly to your available balance (bypassing your pending balance).
4000003720000278 Charge succeeds and funds will be added directly to your available balance (bypassing your pending balance).
4000000000000093 Charge succeeds and domestic pricing is used (other test cards use international pricing). This card is only significant in countries with split pricing.
4000000000000010 The address_line1_check and address_zip_check verifications fail. If your account is blocking payments that fail postal code validation, the charge is declined.
4000000000000028 Charge succeeds but the address_line1_check verification fails.
4000000000000036 The address_zip_check verification fails. If your account is blocking payments that fail postal code validation, the charge is declined.
4000000000000044 Charge succeeds but the address_zip_check and address_line1_check verifications are both unavailable.
4000000000005126 Charge succeeds but refunding a captured charge fails asynchronously with a failure_reason of expired_or_canceled_card. Note that because refund failures are asynchronous, the refund will appear to be successful at first and will only have the failed status on subsequent fetches. We also notify you of refund failures using the charge.refund.updated webhook event.
4000000000000101 If a CVC number is provided, the cvc_check fails. If your account is blocking payments that fail CVC code validation, the charge is declined.
4000000000000341 Attaching this card to a Customer object succeeds, but attempts to charge the customer fail.
4000000000009235 Results in a charge with a risk_level of elevated.
4000000000004954 Results in a charge with a risk_level of highest.
4100000000000019 Results in a charge with a risk_level of highest. The charge is blocked as it's considered fraudulent.
4000000000000002 Charge is declined with a card_declined code.
4000000000009995 Charge is declined with a card_declined code. The decline_code attribute is insufficient_funds.
4000000000009987 Charge is declined with a card_declined code. The decline_code attribute is lost_card.
4000000000009979 Charge is declined with a card_declined code. The decline_code attribute is stolen_card.
4000000000000069 Charge is declined with an expired_card code.
4000000000000127 Charge is declined with an incorrect_cvc code.
4000000000000119 Charge is declined with a processing_error code.
4242424242424241 Charge is declined with an incorrect_number code as the card number fails the Luhn check.

By default, passing address or CVC data with the card number causes the address and CVC checks to succeed. If this information isn't specified, the value of the checks is null. Any expiration date in the future is considered valid.

You can also provide invalid card details to test specific error codes resulting from incorrect information being provided. For example:

  • invalid_expiry_month: Use an invalid month (e.g., 13)
  • invalid_expiry_year: Use a year in the past (e.g., 1970)
  • invalid_cvc: Use a two digit number (e.g., 99)

Disputes

In test mode, you can use the test cards below to simulate a disputed transaction:

Card numbers Tokens PaymentMethods

NUMBER DESCRIPTION
4000000000000259 With default account settings, charge succeeds, only to be disputed as fraudulent. This type of dispute is protected if 3D Secure was run.
4000000000002685 With default account settings, charge succeeds, only to be disputed as product not received. This type of dispute is not protected if 3D Secure was run.
4000000000001976 With default account settings, charge succeeds, only to be disputed as an inquiry.
4000000000005423 With default account settings, charge succeeds, only to receive an early fraud warning.

The following evidence, when submitted in the uncategorized_text, produces specific actions that are useful for testing the dispute flow:

EVIDENCE DESCRIPTION
winning_evidence The dispute is closed and marked as won. Your account is credited the amount of the charge and related fees.
losing_evidence The dispute is closed and marked as lost. Your account is not credited.

Rate limits

It is extremely unlikely for users to experience any rate limits with normal usage of the API, even at high volume. The most common causes for a user to experience rate limits are bugs, bulk data fetches, or extreme load testing.

Should your requests begin to receive 429 HTTP errors, reduce the frequency of your requests. Each failed request is perfectly safe to retry as rate limiting takes place before any other action and prevents the request from being processed. When reducing your request frequency, we recommend an exponential backoff by first waiting one second before trying again. If your request continues to receive the same response, wait two seconds, then four seconds, etc.

The rate limit in test mode is lower than the one in live mode. If you are experiencing rate limits but are unable to determine why, please let us know.

Sources

Use the following information when testing payments using Sources.

click here and download the project source code :  

Contact : support@erps.in (OR) uma@f5craft.com / +91 87784 09644 (OR) +91 93443 88665