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.
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.
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.
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