secux-paymentkit-v2
示例
要运行示例项目,首先克隆仓库,然后在 Example 目录下运行 pod install
。
要求
安装
secux-paymentkit-v2 通过 CocoaPods 提供。要安装该软件包,只需将以下行添加到 Podfile 中:
pod 'secux-paymentkit-v2'
在 plist 中添加蓝牙隐私权限
导入模块
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 文件以获取更多信息。