Hi guys, today we will learn about how to implement PayU Money Payment Gateway for an iOS application in Swift.
Before starting to code first we need to know what a payment gateway is
A payment gateway is an e-commerce system that helps support modern retail or other types of sales of products and services, over the Internet or at brick-and-mortar stores. Payment gateways authorize credit card payments in order to support point-of-sale systems.
Thus, it’s enough for us now. Let’s start by following the instructions below.
STEPS TO INTEGRATE
1.) Add Payu Money SDK to your Project
We can add it by following ways:
a.) By Integrate Payu Money SDK using Cocoa Pods:
To integrate Payu Money into your Xcode project using CocoaPods, specify it as a target in your Podfile:
(i) Add the following lines to Podfile of your project:
1 |
pod 'PayUmoney_PnP' |
(ii) Then, run the following command to install it:
1 |
pod install |
b.) Manually include Payu Money framework in your project :
For manually include the Payu Money framework, you have to follow the given below steps:
(i) Add Payu Money SDK to your project from Github
(ii) Clone or download the framework from the Github.
(iii) Unzip the “PayUMoney-IOS-SDK-master.zip” file and open it.
(iv) Navigate to the “PlugNPlay” folder & drag the PlugNPlay.framework into your project
(v) In Xcode, add the PlugNPlay.framework in Link Binary With Libraries & Embedded Frameworks section.
2.) Import the SDK
After installation, you must import the SDK in your project by adding the following line to the files in which you want to use this framework.
1 |
import PlugNPlay |
3.) Set Payment Params
To start using the PayUmoney PnP SDK, you need you to initialize the SDK by providing details about the customer and the transaction. To initiate the payment, create an object of type ‘PUMTxnParam’ and set all the mandatory parameters as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
func continueWithCardPayment(data: JSON, orderId: String) { let TXNParams = PUMTxnParam() TXNParams.phone = data["payuData"]["telephone"].stringValue TXNParams.email = data["payuData"]["email"].stringValue TXNParams.amount = data["payuData"]["amount"].stringValue if data["payuData"]["sandboxMode"].stringValue == "false" { TXNParams.environment = PUMEnvironment.production } else { TXNParams.environment = PUMEnvironment.test } TXNParams.firstname = data["payuData"]["firstname"].stringValue TXNParams.key = data["payuData"]["key"].stringValue TXNParams.merchantid = data["payuData"]["merchantId"].stringValue TXNParams.txnID = data["payuData"]["txnid"].stringValue TXNParams.surl = data["payment_data"]["surl"].stringValue // "https://www.payumoney.com/mobileapp/payumoney/success.php" TXNParams.furl = data["payment_data"]["furl"].stringValue // "https://www.payumoney.com/mobileapp/payumoney/failure.php" TXNParams.productInfo = data["payuData"]["productInfo"].stringValue TXNParams.udf1 = "" TXNParams.udf2 = "" TXNParams.udf3 = "" TXNParams.udf4 = "" TXNParams.udf5 = "" TXNParams.udf6 = "" TXNParams.udf7 = "" TXNParams.udf8 = "" TXNParams.udf9 = "" TXNParams.udf10 = "" TXNParams.hashValue = self.getHashForPaymentParams(kMerchantSalt: data["payuData"]["salt"].stringValue, TXNParams) PlugNPlay.setMerchantDisplayName(data["payuData"]["merchantId"].stringValue) PlugNPlay.setDisableCompletionScreen(false) PlugNPlay.setOrderDetails([]) PlugNPlay.presentPaymentViewController(withTxnParams: TXNParams, on: self) { (dict, error, value) in print(dict, error, value) let resultData = JSON(dict as Any) if error == nil { print(resultData["result"]["status"].stringValue) } else { print(resultData["result"]["error_Message"].stringValue) } } } |
You can handle success or error events when a payment is completed by “PlugNPlay.presentPaymentViewController“.
4.) Calculate Server-Side Hash
The only server-side change required while integrating the PayU Money SDK is to generate a hash parameter for both the payment request & response.
A hash is an encrypted value (checksum) that is to be sent by the merchant in a payment request and sent by PayU Money in the payment response. A hash is used to protect transactions against “man in the middle attack”.
The SHA512
hash implements the HashFunction
protocol for the specific case of SHA-2 hashing with a 512-bit digest (SHA512Digest
). Larger digests take more space but are more secure.
1 2 3 4 5 6 7 8 9 10 |
extension String { func sha512() -> String { let data = self.data(using: .utf8)! var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH)) data.withUnsafeBytes({ _ = CC_SHA512($0, CC_LONG(data.count), &digest) }) return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "") } } |
1 2 3 4 5 6 7 8 |
func getHashForPaymentParams(kMerchantSalt: String,_ txnParam: PUMTxnParam?) -> String? { let salt = kMerchantSalt var hashSequence: String? = nil if let key = txnParam?.key, let txnID = txnParam?.txnID, let amount = txnParam?.amount, let productInfo = txnParam?.productInfo, let firstname = txnParam?.firstname, let email = txnParam?.email, let udf1 = txnParam?.udf1, let udf2 = txnParam?.udf2, let udf3 = txnParam?.udf3, let udf4 = txnParam?.udf4, let udf5 = txnParam?.udf5, let udf6 = txnParam?.udf6, let udf7 = txnParam?.udf7, let udf8 = txnParam?.udf8, let udf9 = txnParam?.udf9, let udf10 = txnParam?.udf10 { hashSequence = "\(key)|\(txnID)|\(amount)|\(productInfo)|\(firstname)|\(email)|\(udf1)|\(udf2)|\(udf3)|\(udf4)|\(udf5)|\(udf6)|\(udf7)|\(udf8)|\(udf9)|\(udf10)|\(salt)" } return hashSequence?.sha512() } |
Note: The entire hash logic is built on the assumption ‘Salt’ is always safe with the merchant. Hence is very important for the merchant to keep the ‘Salt’ safe by adhering to the best security practices. For eg: Merchant should always compute from the server-side and never from the client-side, should never share the ‘Salt & Key’ over emails or directly commit to public repositories like Github.
5.) Insert the following XML Source Code Snippet Into the Body of Your Info.Plist File Just Before the Final
1 2 3 4 5 |
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> |
Conclusion
So please follow the above step and if you have any issue or suggestion you can leave your query/suggestion in the comment section I will try to solve that.