This is a simple example of integrating Paytm SDK into your iOS app using Swift for accepting payments. It is optimised and tested with the latest Paytm SDK as of March 2019.

Obtain Paytm test credentials

Login to Paytm developer account and on the left-hand side of dashboard click on API key. Copy your test credentials: Test Merchant ID and Test Account Secret Key. These are testing keys; and once you activate your account(Top right Corner), Paytm support team will send you an email with Production key and Merchant ID.

Server-side work: Checksum Kit

Download the Paytm App Checksum Kit PHP folder and upload it to your server root directory. Rename the folder to something simple to your liking.

Go to config_paytm.php (in the lib folder paytm/lib/config_paytm.php), and add your “Test Account Secret Key” credential and save the file.

We just need to route to the generateChecksum.php file. So your checksum URL will look like http://www.your-domain/foldername/generateChecksum.php. Save this URL.

Adding the framework to your project

  1. Go to PayTM iOS App Kit and download the framework named PaymentSDK.framework inside BitCodeEnabled folder.
  2. In your XCode project, go to File menu, and select Add files to YourProjectNameSelect the PaymentSDK.framework and make sure Copy items if needed is checked, click Add.
  3. In your project settings, open the Build Phases tab. Under Link Binary With Libraries, add SystemConfiguration.framework. Make sure PaymentSDK.framework is also listed there.
  4. Go to General tab. Scroll down, and under the Embedded Binaries section, add the PaymentSDK.framework there as well, if not already listed.

Generating checksum from your server using Alamofire

First, add Alamofire to your podfile

  pod 'Alamofire'
  pod 'Alamofire-SwiftyJSON'

Run pod init to install them.

Make a new Config.swift file, and store your credentials and URLs.

class Config {
    static let url_paytm_callback = ""
    static let url_checksum_paytm = "" + "/paytm/" + "generateChecksum.php"

Now open your ViewController where the payment will take place. Add PGTransactionDelegate to it.

class CartVC: UIViewController, PGTransactionDelegate {
    override func viewDidLoad() {


Declare two variables, orderId and custId. Note that these two string should always be unique. Here we will use a random unique string, but later you should use some logic to generate them.

let orderId = "someRandomUniqueString1"
let custId = "someRandomUniqueStringForCustId"

Upon clicking the CHECKOUT or PAY button, call this below function to send a request to your server URL and generate a checksum.

func generateChecksum(orderId: String, custId: String) {

        let params = [
            "MID" :  Config.PAYTM_MERCHANT_ID,
            "ORDER_ID" :  orderId,
            "CUST_ID" :  custId,
            "CHANNEL_ID" :  "WAP",
            "TXN_AMOUNT" :  "100",
            "WEBSITE" :  "WEBSTAGING",
            "CALLBACK_URL" :  Config.url_paytm_callback,
            "INDUSTRY_TYPE_ID" :  "Retail"

        let headers = [
            "Content-Type": "application/x-www-form-urlencoded"

        Alamofire.request(Config.url_checksum_paytm, method: .post, parameters: params, encoding: URLEncoding.default, headers: headers)
            .responseSwiftyJSON(completionHandler: { dataResponse in
                if dataResponse.result.isSuccess {
                    let json = JSON(dataResponse.result.value!)
                    if let checksum = try? self.decoder.decode(Checksum.self, from: json.rawData()) {
                        self.beginPayment(checksumhash: checksum.CHECKSUMHASH)

                if dataResponse.result.isFailure {
                    let error : Error = dataResponse.result.error!
                    print("error in checksum url")

Now write the beginPayment() function to start the payment view once a checksum is received

func beginPayment(checksumhash: String) {

        let type: ServerType = .eServerTypeStaging
        let order = PGOrder(orderID: orderId, customerID: custId, amount: "", eMail: "", mobile: "")
        order.params = ["MID": Config.PAYTM_MERCHANT_ID,
                        "ORDER_ID": orderId,
                        "CUST_ID": custId,
                        "CHANNEL_ID": "WAP",
                        "WEBSITE": "WEBSTAGING",
                        "TXN_AMOUNT": "100.12",
                        "INDUSTRY_TYPE_ID": "Retail",
                        "CHECKSUMHASH": checksumhash,
                        "CALLBACK_URL": Config.url_paytm_callback

        var txnController = PGTransactionViewController()
        txnController = txnController.initTransaction(for: order) as! PGTransactionViewController
        txnController.title = "Paytm Payments"
        if(type != ServerType.eServerTypeNone) {
            txnController.serverType = type;
        } else { return }
        txnController.merchant = PGMerchantConfiguration.defaultConfiguration()
        txnController.delegate = self
        self.navigationController?.pushViewController(txnController, animated: true)

Implement delegate functions

func didFinishedResponse(_ controller: PGTransactionViewController, response responseString: String) {
    let msg : String = responseString
    var titlemsg : String = ""
    if let data = String.Encoding.utf8) {
        do {
            if let jsonresponse = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any] , jsonresponse.count > 0{
               titlemsg = jsonresponse["STATUS"] as? String ?? ""
        } catch {
            print("Something went wrong")
    let actionSheetController: UIAlertController = UIAlertController(title: titlemsg , message: msg, preferredStyle: .alert)
    let cancelAction : UIAlertAction = UIAlertAction(title: "OK", style: .cancel) {
        action -> Void in
        controller.navigationController?.popViewController(animated: true)
    self.present(actionSheetController, animated: true, completion: nil)

func didCancelTrasaction(_ controller: PGTransactionViewController) {
func errorMisssingParameter(_ controller: PGTransactionViewController, error: NSError?) {