Integration Steps
The iOS Checkout Pro SDK integration involves the following steps:
SDK Integration
Prerequisite: Create a PayU account
First, create a PayU account. For more information, refer to Register for a Merchant Account.
Step 1: Set up pod
The CheckoutPro SDK is offered through CocoaPods. To add the SDK in your app project:
Include the SDK framework in your podfile.
// make sure to add below-mentioned line to use dynamic frameworks
use_frameworks!
// Add this to include our SDK
pod 'PayUIndia-CheckoutPro'
- Install dependency using the pod install command in terminal
- Add the following imports in the class where you need to initiate a payment.
import PayUCheckoutProKit
import PayUCheckoutProBaseKit
import PayUParamsKit
#import <PayUCheckoutProKit/PayUCheckoutProKit.h>
#import <PayUCheckoutProBaseKit/PayUCheckoutProBaseKit.h>
#import <PayUBizCoreKit/PayUBizCoreKit.h>
#import <PayUParamsKit/PayUParamsKit.h>
- Refer to the following Test the key and salt environments:
- Production: Generate Production Merchant Key and Salt
- Test: Generate Test Merchant Key and Salt
Swift Package Manager Integration
You can integrate PayUIndia-Checkoutpro with your app or SDK using the following methods:
- Using Xcode: Navigate to File > Add Package menu and add the following package: https://github.com/payu-intrepos/PayUCheckoutPro-iOS
- Using Package.Swift: Add the following line in the Package.swift dependencies:
.package(name: "PayUCheckoutProKit", url: "https://github.com/payu-intrepos/PayUCheckoutPro-iOS", from: "7.4.0")
CrashReporter
In order to receive all the crashes related to our SDKs, add the following line to your AppDelegate didFinishLaunchingWithOptions
method:
PayUDontUseThisClass.integrateCrashReporter()
[PayUDontUseThisClass integrateCrashReporter];
Step 2: Build the payment parameters (mandatory step)
Step 2.1: Basic Integration
PayU SDK needs certain inputs from the merchant app to authenticate and initiate a transaction.
Mandatory parameters
Use the following table to pass the mandatory parameters in the PayU SDK:
Parameter | Description | Required |
---|---|---|
key | Merchant Key provided by PayU during onboarding. | Yes |
transactionId | A unique ID passed by the merchant for each transaction. | Yes |
amount | The transaction amount. | Yes |
productInfo | A brief description of the product. | Yes |
firstName | Customer's first name. | Yes |
Customer's email address. | Yes | |
phone | Customer's phone number. | Yes |
surl | Success URL - where the customer is redirected after a successful payment | Yes |
furl | Failure URL - where the customer is redirected after an unsuccessful/failed payment | Yes |
environment | The environment in which the transaction is initiated. For TEST transactions, use PayUTestEnvironment. For LIVE transactions, use PayUProdEnvironment. | Yes |
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
.setAmount("10")
.setProductInfo("PRODUCT_INFO")
.setFirstName("FIRSTNAME")
.setEmail("EMAIL")
.setPhone("1234567890")
.setSurl("SUCCESS_URL")
.setFurl("FAILURE_URL")
.setEnvironment(PayUTestEnvironment) // PayUProdEnvironment
.build()
PayUPaymentParamsBuilder *paymentParamsBuilder = [PayUPaymentParamsBuilder new];
[paymentParamsBuilder setKey:@"MERCHANT_KEY"];
[paymentParamsBuilder setTransactionId:@"TRANSACTION_ID"];
[paymentParamsBuilder setAmount:@"10"];
[paymentParamsBuilder setProductInfo:@"PRODUCT_INFO"];
[paymentParamsBuilder setFirstName:@"FIRSTNAME"];
[paymentParamsBuilder setEmail:@"EMAIL"];
[paymentParamsBuilder setPhone:@"1234567890"];
[paymentParamsBuilder setSurl:@"SUCCESS_URL"];
[paymentParamsBuilder setFurl:@"FAILURE_URL"];
[paymentParamsBuilder setEnvironment:PayUTestEnvironment]; // PayUProdEnvironment
PayUPaymentParams *payUPaymentParams = [paymentParamsBuilder build];
Step 2.2:For Recurring Payments(SI) (Optional)
For setting up Standing Instructions (SI) or recurring payments, you can refer to the Recurring Payments Documentation.
Use the following sample code:
let payUSIDetailsBuilder = PayUSIDetailsBuilder()
.setBillingAmount("100")
.setBillingInterval(PayUBillingInterval.monthly)
.setPaymentStartDate(date)
.setPaymentEndDate(date)
.setBillingCycle("50")
.setRemarks("Test SI Transaction")
.setBillingRule(PayUBillingRule.max)
.build()
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
.setAmount("10")
.setProductInfo("PRODUCT_INFO")
.setFirstName("FIRSTNAME")
.setEmail("EMAIL")
.setPhone("1234567890")
.setSurl("SUCCESS_URL")
.setFurl("FAILURE_URL")
.setEnvironment(PayUTestEnvironment)
.setPayUSIDetails(payUSIDetailsBuilder)
.build()
Step 2.3:For UPI One Time Mandate Payments (Optional)
For UPI One Time Mandate (OTM) payments, use the following parameters:
let payUUPIOTMDetailsBuilder = PayUUPIOTMDetailsBuilder()
.setNotificationUrl("NOTIFICATION_URL")
.setOtmType(PayUOTMType.opt_in)
.build()
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
.setAmount("10")
.setProductInfo("PRODUCT_INFO")
.setFirstName("FIRSTNAME")
.setEmail("EMAIL")
.setPhone("1234567890")
.setSurl("SUCCESS_URL")
.setFurl("FAILURE_URL")
.setEnvironment(PayUTestEnvironment)
.setPayUUPIOTMDetails(payUUPIOTMDetailsBuilder)
.build()
Step 2.4: For Split Payments details (Optional)
Split payments allow you to distribute the payment amount between a parent merchant and sub-merchants.
JSON request structure of splitInfo field
{
"type": "absolute",
"splitInfo": {
"merchant_05Apr16_126800": {
"aggregatorSubTxnId": "aggregatorSubTxnId1",
"aggregatorSubAmt": "50"
},
"merchant_05Apr16_780908": {
"aggregatorSubTxnId": "aggregatorSubTxnId2",
"aggregatorSubAmt": "30"
}
}
}
Example implementation:
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
.setAmount("100")
.setProductInfo("PRODUCT_INFO")
.setFirstName("FIRSTNAME")
.setEmail("EMAIL")
.setPhone("1234567890")
.setSurl("SUCCESS_URL")
.setFurl("FAILURE_URL")
.setEnvironment(PayUTestEnvironment)
.setSplitPaymentsDetails("SPLIT_PAYMENTS_DETAILS_JSON")
.build()
Step 2.4:For Additional Charges
Additional charges can be applied to transactions:
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
.setAmount("100")
.setProductInfo("PRODUCT_INFO")
.setFirstName("FIRSTNAME")
.setEmail("EMAIL")
.setPhone("1234567890")
.setSurl("SUCCESS_URL")
.setFurl("FAILURE_URL")
.setEnvironment(PayUTestEnvironment)
.setAdditionalCharges("ADDITIONAL_CHARGES_JSON")
.build()
Step 3: Set up the payment hashes
PayU uses hashes to ensure the integrity and security of the transaction.
Getting Hash Data to calculate hash
In order to authenticate a payment request and to ensure the data security of the payment request, PayU requires hash values to be calculated.
func generateHash(_ param: DictOfString, onCompletion: @escaping PayUHashGenerationCompletionBlock) {
// Process the param dictionary and calculate hashes on your backend server
// Return the calculated hashes
let hashes = ["hash_key": "calculated_hash_value"]
onCompletion(hashes)
}
Passing generated hash to SDK
Once you have the hash values, pass them to the SDK:
PayUCheckoutPro.open(payUPaymentParams,
payUConfig: payUConfig,
parentVC: self,
hashGenerationCompletionBlock: generateHash,
paymentCompletionBlock: paymentCompletionBlock)
Step 4: Initiate the payment
After setting up the payment parameters and hashes, initiate the payment:
PayUCheckoutPro.open(payUPaymentParams,
payUConfig: payUConfig,
parentVC: self,
hashGenerationCompletionBlock: generateHash,
paymentCompletionBlock: paymentCompletionBlock)
[PayUCheckoutPro open:payUPaymentParams
payUConfig:payUConfig
parentVC:self
hashGenerationCompletionBlock:generateHash
paymentCompletionBlock:paymentCompletionBlock];
Step 5: Handle the payment completion
Handle the response when the payment is completed:
Sample Responses
Successful Payment Response:
{
"result": {
"payuResponse": "response_data",
"merchantResponse": "merchant_response_data"
},
"status": "success"
}
Failed Payment Response:
{
"result": {
"payuResponse": "response_data",
"merchantResponse": "merchant_response_data"
},
"status": "failure"
}
Cancelled Payment Response:
{
"result": "Transaction was cancelled by user",
"status": "user_cancelled"
}
UPI Intent (Optional)
For UPI Intent functionality:
let payUConfig = PayUConfigBuilder()
.setPaymentModesOrder([PayUPaymentModeConfig.upi()])
.setShouldShowPaymentModes(false)
.build()
Test the Integration
Card/NB/Wallet and other transactions
For testing various payment methods, use the following test credentials:
Test Credit Cards:
- Visa: 4444333322221111
- MasterCard: 5123456789012346
- Maestro: 5081597022059105
Test Debit Cards:
- Visa: 4000111122223331
- MasterCard: 5123456789012346
All test cards use:
- CVV: Any 3 digit number
- Expiry Date: Any future date
UPI Collect/Intent payments
For testing UPI payments:
Test VPA: success@payu
This VPA will simulate a successful UPI transaction for testing purposes.
Distributing your app (App Store / Ad-hoc)
When distributing your app, ensure:
- Use production keys for live transactions
- Test thoroughly with production credentials
- Follow App Store guidelines for payment apps
- Ensure all required permissions are in place
Additional integration
Step 1: Create a Custom Note list
You can create custom notes for transactions:
let customNoteDetails = PayUCustomNoteDetailsBuilder()
.setCustomNote("Custom transaction note")
.setCustomNoteCategory("CATEGORY")
.build()
Step 2: Pass the Custom Note list to SDK
Pass the custom notes to the payment parameters:
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
// ... other parameters
.setCustomNoteDetails([customNoteDetails])
.build()
Test credentials for supported payment methods
Test cards for EMI
For testing EMI transactions:
EMI Test Cards:
- HDFC: 4444333322221111
- ICICI: 5123456789012346
- SBI: 4000111122223331
All EMI test cards use:
- CVV: 123
- Expiry: 12/25
Test credentials for Net Banking
Net Banking Test Credentials:
- SBI: Use any valid account number
- HDFC: Use any valid customer ID
- ICICI: Use any valid user ID
- Axis: Use any valid user ID
For all banks, use any password for testing.
Test VPA for UPI
UPI Test VPAs:
- Success:
success@payu
- Failure:
failure@payu
- Pending:
pending@payu
Test wallets
Wallet Test Credentials:
- Paytm: Use mobile number 7777777777
- PhonePe: Use mobile number 9999999999
- Amazon Pay: Use mobile number 8888888888
Use OTP: 123456 for all wallet testing.
Go-live Checklist
Collect Live Payments
Before going live, ensure you have:
- Production Merchant Key and Salt
- KYC Completed
- Live Testing Done
- Error Handling Implemented
- Security Best Practices Followed
Checklist 2: Configure environment
Set the environment to production:
.setEnvironment(PayUProdEnvironment)
Ensure all production URLs and keys are correctly configured.
Checklist 3: Configure your SURL/FURL
Set up your production Success URL (SURL) and Failure URL (FURL):
- SURL: Where users are redirected after successful payment
- FURL: Where users are redirected after failed payment
These URLs should handle payment responses appropriately and show relevant messages to users.
Checklist 4: Configure verify payment method
Implement payment verification on your backend:
// Always verify payment status from your backend using PayU's verify API
// Do not rely solely on the mobile response for order fulfillment
Use PayU's verification API to confirm payment status before order fulfillment.
Checklist 5: Configure Webhook
Set up webhooks to receive payment notifications:
- Configure webhook URL in PayU dashboard
- Implement webhook handler on your backend
- Verify webhook authenticity using provided hash
- Process payment updates asynchronously
Example webhook structure:
{
"mihpayid": "transaction_id",
"status": "success",
"amount": "100.00",
"txnid": "merchant_txn_id"
}
Integrate convenience fee
To integrate convenience fees:
let payUPaymentParams = PayUPaymentParamsBuilder()
.setKey("MERCHANT_KEY")
.setTransactionId("TRANSACTION_ID")
// ... other parameters
.setConvenienceFee("CONVENIENCE_FEE_JSON")
.build()
The convenience fee JSON should contain fee structure for different payment modes.
Updated 4 days ago