secux-paymentkit-v2 2.1.19

secux-paymentkit-v2 2.1.19

SecuX 维护。



  • 作者
  • maochuns

secux-paymentkit-v2

CI Status Version License Platform

示例

要运行示例项目,首先克隆仓库,然后在 Example 目录下运行 pod install

要求

安装

secux-paymentkit-v2 通过 CocoaPods 提供。要安装该软件包,只需将以下行添加到 Podfile 中:

pod 'secux-paymentkit-v2'

在 plist 中添加蓝牙隐私权限

Screenshot

导入模块

    import secux_paymentkit_v2

使用方法

1. 初始化

所有三个初始化函数都应该在应用启动时完成。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions... {
    
    //Initialization functions here

}

使用SecuXAccountManager对象执行以下操作。

    let accManager = SecuXAccountManager()

1.1 设置服务器地址

    Set server URL before using the APIs below

声明

    func setBaseServer(url:String)

参数

    Server URL. e.g. https://pmsweb-test.secux.io

示例

    let accMgr = SecuXAccountManager()
    let serverUrl = "https://pmsweb-test.secux.io"
    accMgr.setBaseServer(url: serverUrl)

1.2 设置管理员账户和密码

Set the administractor account, which is assigned to customers by SecuX

声明

    func setAdminAccount(name:String, password:String)

参数

    name:       Administractor account name.
    password:   Administractor account password.

示例

    let accMgr = SecuXAccountManager()
    accMgr.setAdminAccount(name:"testAccount", password:"12345678")

2. SecuXAccount 相关操作

使用 SecuXAccountManager 对象执行以下操作

    let accManager = SecuXAccountManager()

2.1 获取支持的币种/代币

声明

    func getSupportedCoinTokenArray() 
            -> (SecuXRequestResult, Data?, [(coin:String, token:String)]?)

返回值

    SecuXRequestResult shows the operation result, if the result is  
    SecuXRequestResult.SecuXRequestOK, the returned array contains all the supported 
    coin and token pairs, otherwise data might contain an error message.  

示例

    let (ret, data, coinTokenArray) = accManager.getSupportedCoinTokenArray()
    guard ret == SecuXRequestResult.SecuXRequestOK else{
        var error = ""
        if let data = data{
            error = String(data: data, encoding: .utf8) ?? ""
        }
        print("Error: \(error)")
        
        return
    }
    
    if let coinTokenArr = coinTokenArray{
        for item in coinTokenArr{
            print("coin=\(item.coin) token=\(item.token)")
        }
    }

2.2 注册

Register a new user account with specified coin/token account. Please note the registration operation may take around 15 seconds to set up.

声明

    func registerUserAccount(userAccount: SecuXUserAccount, 
                                coinType: String, 
                                   token: String) -> (SecuXRequestResult, Data?)

参数

    userAccount: A SecuXUserAccount object with login name and password  
    coinType:    Coin type string  
    token:       Token string

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK,
    registration is successful, otherwise data might contain an error message.

    Note: if return result is SecuXRequestNoToken, the administractor account is not correct.

示例

    let usrAcc = SecuXUserAccount(email: name, password: pwd)
    var (ret, data) = accManager.registerUserAccount(userAccount: usrAcc, 
                                                        coinType: "DCT", 
                                                           token: "SPC")
    
    if ret == SecuXRequestResult.SecuXRequestOK{
        //Login the account
        ...
    }else{
        var errorMsg = ""
        if let data = data, let error = String(data: data, encoding: String.Encoding.utf8){
            errorMsg = error
        }
        print("Registration failed! error \(error)")
    }

2.3 登录

注意:登录会话有效期为30分钟。超过30分钟后,为了继续使用,需要进行重新登录。

声明

    func loginUserAccount(userAccount:SecuXUserAccount) -> (SecuXRequestResult, Data?)

参数

    userAccount: A SecuXUserAccount object with login name and password  

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    login is successful, otherwise data might contain an error message.

示例

    let accManager = SecuXAccountManager()
    let usrAcc = SecuXUserAccount(email: name, password: pwd)
    
    var (ret, data) = accManager.loginUserAccount(userAccount: usrAcc)
    if ret == SecuXRequestResult.SecuXRequestOK{
        
        //Login successfully
        ...
        
    }else{
        var errorMsg = "Invalid email/password!"
        if let data = data, let error = String(data: data, encoding: String.Encoding.utf8){
            errorMsg = error
        }
        print("Login failed! error \(error)")
    }

2.4 获取代币/账户列表

Must successfully login the server before calling the function. Return all the coin/token accounts belongs to the login user.

声明

    func getCoinAccountList(userAccount:SecuXUserAccount) -> (SecuXRequestResult, Data?)

参数

    userAccount: Successfully logined user account.

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    getting coin/token account information is successful and coin/token account 
    information is in the user account's coinAccountArray, otherwise data might contain  
    an error message.

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.

示例

    let (ret, data) = accManager.getCoinAccountList(userAccount: usrAcc)
    if ret == SecuXRequestResult.SecuXRequestOK{    
        for coinAcc in usrAcc.coinAccountArray{
            let tokenArr = coinAcc.tokenBalanceDict.keys
            for token in tokenArr{
                print("coin/token account: \(coinAcc.coinType) \(token)")
            }
        }
    }else{
        var errorMsg = ""
        if let data = data, let error = String(data: data, encoding: String.Encoding.utf8){
            errorMsg = error
        }
        print("Get coin/token info. failed! error \(error)")
    }

2.5 获取代币/账户余额

Must successfully login the server before calling the function. Return the coin/token account balance

声明

    func getAccountBalance(userAccount:SecuXUserAccount, 
                              coinType: String? = nil, 
                                 token: String? = nil) -> (SecuXRequestResult, Data?)

参数

    userAccount: A SecuXUserAccount object with login name and password  
    coinType:    CoinType string  
    token:       Token string

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    getting coin/token account balance is successful and coin/token account balance can 
    be found in the user account's coinAccountArray, otherwise data might contain 
    an error message.

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.

示例

    let (ret, data) = accManager.getAccountBalance(userAccount: usrAcc, 
                                                   coinType: "DCT", token: "SPC")
                
    guard ret == SecuXRequestResult.SecuXRequestOK else{
        print("get \(coinAcc.coinType) \(token) balance failed")
        if let data = data{
            print("Error: \(String(data: data, encoding: String.Encoding.utf8) ?? "")")
        }
        continue
    }
    
    let coinAcc = usrAcc.getCoinAccount(coinType: "DCT")
    if let tokenBal = coinAcc.tokenBalanceDict["SPC"]{
        print("\(coinAcc.coinType) \(token) \(tokenBal.theBalance) 
               \(tokenBal.theFormattedBalance) \(tokenBal.theUsdBalance)")
    }

2.6 更改用户登录密码

    Must successfully login the server before calling the function. 

声明

    func changePassword(oldPwd: String, newPwd: String) -> (SecuXRequestResult, Data?)

参数

    oldPwd: User current login password.
    newPwd: User new login password.

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    password is changed successfully, otherwise data might contain  
    an error message.

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.

示例

    DispatchQueue.global(qos: .default).async {
        let accMgr = SecuXAccountManager()
        let (ret, data) = accMgr.changePassword(oldPwd: oldpwd, newPwd: pwd)
        
        if ret == SecuXRequestResult.SecuXRequestOK{
            
            //Change password done
            
        }else{
            var error = ""
            if let errData = data{
                error = String(data: errData, encoding: String.Encoding.utf8) ?? ""
            }
            self.showMessageInMainThread(title: "Change password failed", message:error)
        }
        
    }

使用SecuXPaymentManager对象执行以下操作

    let paymentManager = SecuXPaymentManager()

3.1 解析支付二维码/NFC消息

    func getPaymentInfo(paymentInfo: String)->(SecuXRequestResult, Data?)

    paymentInfo: Payment QRCode from P20/P22, or NFC string from P20/P22

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    parsing payment information is successful and data contains decoded payment 
    information in JSON format , otherwise data might contain an error message.

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.


    Sample return JSON format
    {
        "amount": "10",
        "coinType": "DCT:SPC",
        "deviceID": "4ab10000726b",
        "deviceIDhash": "41193D32D520E114A3730D458F4389B5B9A7114D"
    }
    
    Note: "amount" and "coinType" are optional, QRCode from P20 will not generate 
    these items.

    let (ret, data) = paymentManager.getPaymentInfo(paymentInfo: paymentInfo)
    if ret == SecuXRequestResult.SecuXRequestOK, let data = data{
        print("get payment info. done")
        guard let responseJson = try? JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] else{
            print("Invalid json response from server")
            return
        }
        
        guard let devIDHash = responseJson["deviceIDhash"] as? String else{
            print("Response has no hashed devID")
            return
        }

        var amount = "0"
        if let amountinfo = payinfoJson["amount"] as? String, amountinfo != "null"{
            amount = amountinfo
        }
        
        var cointype = ""
        var token = ""
        if let type = payinfoJson["coinType"] as? String, type != "null"{
            
            if let pos = type.firstIndex(of: ":"){
                cointype = String(type[..<pos])
                token = String(type[type.index(after: pos)...])
            }
        }       
    }

3.2 获取商家信息

    func getStoreInfo(devID:String) -> (SecuXRequestResult, String, SecuXStoreInfo?)

    devID: Hashed device ID from the "getPaymentInfo" function

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    getting store information is successful, retuned store info. object contrains all the store related information, e.g. name, logo..., otherwise data might contain an error message.

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.

示例

    let (reqRet, error, info) = paymentManager.getStoreInfo(devID: devIDHash)
            
    guard reqRet == SecuXRequestResult.SecuXRequestOK, 
        let storeInfo = info, 
        let imgStore = storeInfo.logo,
        storeInfo.coinTokenArray.count > 0, 
        storeInfo.name.count > 0 else {
           
            self.showMessageInMainThread(title: "Get store information from server failed!", message: error)
            return
    }
            

3.3 进行支付

声明

    func doPaymentAsync(storeInfo: String, paymentInfo: String)

参数

    storeInfo:   Store information JSON string from the info value of the SecuXStoreInfo object
    paymentInfo: Payment information JSON string. 
    

委托

    protocol SecuXPaymentManagerDelegate{
        func paymentDone(ret: Bool, transactionCode:String, errorMsg: String)
        func updatePaymentStatus(status: String)
    }
    paymentDone: Called when payment is completed. 
                 Returns payment result and an error message.

    updatePaymentStatus: Called when payment status is changed. 
                         Payment status are: 
                         "Device connecting...", 
                         "DCT transferring..."  
                         "Device verifying..."

    Note: You must implement the SecuXPaymentManagerDelegate and set it to the 
    SecuXPayment delegate, e.g. self.paymentManager.delegate = self

示例

class ViewController: UIViewController {

    ...

    func doPayment(){

        ...

        let (reqRet, error, info) = paymentManager.getStoreInfo(devID: devIDHash)
        guard reqRet == SecuXRequestResult.SecuXRequestOK, 
        let storeInfo = info, 
        let imgStore = storeInfo.logo,
        storeInfo.coinTokenArray.count > 0, 
        storeInfo.name.count > 0 else {
             
                self.showMessageInMainThread(title: "Get store information from server failed!", message: error)
                return
        }

        var payinfoDict = [String : String]()
        payinfoDict["amount"] = "12"
        payinfoDict["coinType"] = "DCT"
        payinfoDict["token"] = "SPC"
        payinfoDict["deviceID"] = deviceID
        
        guard let jsonData = try? JSONSerialization.data(withJSONObject: payinfoDict, options: []),
            let paymentInfo = String(data: jsonData, encoding: String.Encoding.utf8) else{
                self.showMessage(title: "Invalid payment information", message: "Payment abort!")
                return
        }

        paymentManager.doPaymentAsync(storeInfo: storeInfo.info, 
                                    paymentInfo: paymentInfo)
    }
}

extension ViewController: SecuXPaymentManagerDelegate{
    
    func paymentDone(ret: Bool, transactionCode: String, errorMsg: String) {
        print("paymentDone \(ret) \(transactionCode) \(errorMsg)")
        
        if ret{
            
            showMessage(title: "Payment success!", message: "")
            let (ret, payhis) = self.paymentManager.getPaymentHistory(token:"SPC", transactionCode: transactionCode)
            if ret == SecuXRequestResult.SecuXRequestOK, let his = payhis{
                print("payment detail: \(his.amount) \(his.storeName) \(his.storeID) \(his.storeTel) \(his.storeAddress)")
            }
        }else{
            showMessage(title: "Payment fail!", message:errorMsg)
        }
    }
    
    func updatePaymentStatus(status: String) {
        print("updatePaymentStatus \(status)")
    }
}

3.4 获取所有支付记录

声明

    func getPaymentHistory(token:String, pageIdx:Int, pageItemCount: Int)
                                        ->(SecuXRequestResult, [SecuXPaymentHistory])  

参数

    token:          Payment token, can be empty
    pageIdx:        History item page index starts from 0, e.g. 0,1,2,3...
    pageItemCount:  Number of history items request, e.g. 5, 10, 20 ... 

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    SecuXPaymentHistory objects are in the returned array. If number of the history 
    objects in the return array less than the input pageItemCount, there is no 
    more history items. 

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.

示例

    var pageIdx = 0
    let pageItemCount = 20

    while (true){
        let (ret, payHisArr) = paymentManager.getPaymentHistory(token: "", 
                                                            pageIdx: pageIdx, 
                                                            pageItemCount: pageItemCount)
        if ret != SecuXRequestResult.SecuXRequestOK{
            print("get payment history failed \(ret)")
            return
        }
        
        var idx = 0
        for payHis in payHisArr{
            print("\(idx) \(payHis.coinType) \(payHis.token) \(payHis.transactionTime) 
                   \(payHis.amount) \(payHis.detailsUrl)")
            idx += 1
        }
        
        if payHisArr.count < pageItemCount{
            break
        }
        
        pageIdx += 1
    }

3.5 根据交易码获取支付历史

声明

    func getPaymentHistory(token:String, transactionCode:String)
                                    ->(SecuXRequestResult, SecuXPaymentHistory?)

参数

    token:           Payment token, e.g. SPC, DCT
    transactionCode: Payment transaction code from SecuXPaymentManagerDelegate when 
                     payment done

返回值

    SecuXRequestResult shows the operation result. If the result is SecuXRequestOK, 
    payment history is in the returned SecuXPaymentHistory object.

    Note: if return result is SecuXRequestNoToken / SecuXRequestUnauthorized, the login 
    session is timeout, please relogin the system.

示例

    let (ret, payhis) = self.paymentManager.getPaymentHistory(token:"SPC", 
                                                    transactionCode: transactionCode)
    if ret == SecuXRequestResult.SecuXRequestOK, let his = payhis{
        print("payment detail: \(his.amount) \(his.storeName) \(his.storeID) 
                               \(his.storeTel) \(his.storeAddress)")
    }

作者

maochuns, [email protected]

许可证

secux-paymentkit 在 MIT 许可证下可用。请问查看 LICENSE 文件以获取更多信息。