15.9 C
London
Friday, September 20, 2024

relaxation – Is there a approach for an iOS app to combine with the PayFast API


I’m trying to implement a fee system utilizing the PayFast on-line funds platform. I made a decision to start out by testing the ping response from the offered documentation hyperlink

from the docs, the next are the required parameters

from the docs, the following are the required parameters

  • merchant-id,integer, 8 char | REQUIRED – I’ve created a take a look at account, which has the ID of 22307768
  • model string | REQUIRED – v1
  • timestamp, ISO-8601 date and time | REQUIRED – generated on the fly by a way in my code
  • signature, string | REQUIRED – generated by a way in my code

From the docs, one has to make use of the next code to generate a signature

import hashlib
import urllib.parse

pfData = {
    "merchant_id": "10000100",
    "merchant_key": "46f0cd694581a",
    "return_url": "https://www.instance.com",
    "notify_url": "https://www.instance.com/notify_url",
    "m_payment_id": "UniqueId",
    "quantity": "200",
    "item_name": "take a look at product"
}

def generateApiSignature(dataArray, passPhrase=""):
    payload = ""
    if passPhrase != '':
        dataArray['passphrase'] = passPhrase
    sortedData = sorted (dataArray)
    for key in sortedData:
        # Get all the information from Payfast and put together parameter string
        payload += key + "=" + urllib.parse.quote_plus(dataArray[key].change("+", " ")) + "&"
    # After looping via, minimize the final & or append your passphrase
    payload = payload[:-1]
    return hashlib.md5(payload.encode()).hexdigest()

passPhrase="jt7NOE43FZPn"
signature = generateApiSignature(pfData, passPhrase)

Since I’m implementing this inside SwiftUI, I transformed the code to Swift, imported CryptoKit and applied the next as my signature era technique

    let pfData: [String: String] = [
        "merchant_id": "22307768",
        "merchant_key": "6p4d8gqkymobf", //from my Payfast test account
        "return_url": "https://www.example.com",
        "notify_url": "https://www.example.com/notify_url",
        "m_payment_id": "UniqueId",
        "amount": "200",
        "item_name": "test product"
    ]

func generateApiSignature(dataArray: [String: String], passPhrase: String = "") -> String {
    var payload = ""
    
    let sortedData = Array(dataArray.keys).sorted()
    for key in sortedData {
        // Get all the information from Payfast and put together the parameter string
        if let worth = dataArray[key]?.replacingOccurrences(of: "+", with: " ") {
            payload += key + "=" + worth.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + "&"
        }
    }
    
    // After looping via, minimize the final "&" or append your passphrase
    payload = String(payload.dropLast())
    if !passPhrase.isEmpty {
        payload += passPhrase
    }
    
    let signature = Insecure.MD5.hash(knowledge: Knowledge(payload.utf8)).map { String(format: "%02hhx", $0) }.joined()
    
    print(signature)
    return signature
}

I then created my easy PingCheckerView as follows

struct PingCheckerView: View {
    @State personal var pingResponse: String = ""
    let passPhrase = "/F/canmak3y0ul0v3m3aga/n" //set inside my Payfast take a look at account

    
    var physique: some View {
        VStack {
            Textual content("Ping Response:")
                .font(.headline)
            
            Textual content(pingResponse)
                .font(.subheadline)
            
            Button("Examine Ping") {
                sendPingRequest()
            }
            .padding()
            .background(Coloration.blue)
            .foregroundColor(.white)
            .cornerRadius(10)
        }
    }
    
    func sendPingRequest() {
        let url = URL(string: "https://api.payfast.co.za/ping?testing=true")!
        
        // Set header parameters
        let headers = [
            "merchant-id": "22307768",
            "version": "v1",
            "timestamp": getCurrentTimestamp(),
            "signature": generateApiSignature(dataArray: pfData, passPhrase: passPhrase)
        ]
        
        // Create request
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.allHTTPHeaderFields = headers
        
        // Ship request
        URLSession.shared.dataTask(with: request) { (knowledge, response, error) in
            if let error = error {
                print("Error: (error.localizedDescription)")
                return
            }
            
            if let knowledge = knowledge {
                if let pingResponse = String(knowledge: knowledge, encoding: .utf8) {
                    DispatchQueue.most important.async {
                        self.pingResponse = pingResponse
                    }
                }
            }
        }.resume()
    }
    
    func getCurrentTimestamp() -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
        let timestamp = formatter.string(from: Date())
        print(timestamp)
        return timestamp
    }
    
}

Nevertheless once I run this, I preserve getting an error 401, “service provider not discovered” response

error 401 Payfast response

I’m not sure why that is the case, my credentials are dwell and proper from inside my Payfast account

payfast credentials

In an effort to find out whether or not this was an Xcode subject, I went on this hyperlink given at on the Payfast sandbox. I proceeded import and run the API name inside one in every of my Postman workspaces

I handed in my merchant-id, timestamp, and mD5 string signature as proven within the screengrab under

postman api call

Once I make the decision, I get the next error message contained in the Postman console, as proven under

postman api call error

I’m on my final legs right here, I’ve used Payfast gateway a while up to now with on web site, by merely directing the consumer to a payfast server URL with all of the required transaction parameters within the question string. With this technique, the server then sends the consumer to a fee display, which prompts the consumer to enter their card particulars. When the fee goes via, the consumer is shipped to a return URL which I pre-selected on my web site to obtain fee notifications on my finish.

On condition that the iOS app I’m constructing just isn’t web-based, I’m trying to do the identical. I’m conscious that I can use a Webview, nevertheless the difficulty is that I’m not fairly sure how I’ll obtain transaction notifications as on condition that we would not have a return URL to ship the consumer to

Taking a look at Payfast documentation I can not make heads or tails of how to do that.

Any assist could be appreciated. I’m required to make use of Payfast as my fee gateway, since among the main suppliers similar to Stripe stay unavailable in South Africa presently.

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here