PayMESDK 0.9.65

PayMESDK 0.9.65

khoatmPayMESDK-iOSnamptMinh Dat 维护。



 
依赖
CryptoSwift>= 0
SwiftyRSA>= 0
Alamofire>= 0
lottie-ios< 4.0
RxSwift>= 0
RxCocoa>= 0
SVGKit>= 0
SwiftyJSON>= 0
Toast-Swift>= 0
PayCardsRecognizer>= 0
 

PayMESDK 0.9.65

  • 作者
  • HuyOpen

PayME SDK 是一套库,允许应用程序与 PayME 平台交互。PayME SDK 包括以下主要功能:

  • PayME 钱包账户的登录和管理
  • 支持应用程序获取 PayME 钱包的余额信息
  • 从 PayME 钱包中充值和提现的功能。

一些术语解释:

名称 解释
1 app 它是 iOS/Android 移动应用程序或 Web 应用程序,将 SDK 集成进来以实现 PayME 钱包的支付功能。
2 SDK 它是支持应用程序集成 PayME 钱包的一套工具。
3 backend 它是支持应用程序、服务器或 API 的一套集成系统。
4 AES AES256 PKCS5 数据加密函数。 查看
5 RSA 数据加密 RSA 算法。
6 IPN Instant Payment Notification,用于在应用程序后端和 PayME 后端之间通信。

安装方法

PayMESDK 存储在 CocoaPods 平台上。要安装,只需在 Podfile 中添加以下行

pod 'PayMESDK'

然后运行 pod install 命令以完成安装

Info.plist

请更新应用程序的 Info.plist 文件,包括以下 key(字符串值可更改,这是请求用户授权时显示的消息)

<key > NSCameraUsageDescription </ key>
<string > Need to access your camera to capture a photo add and update profile picture .</ string>
<key > NSPhotoLibraryAddUsageDescription </ key>
<string > Need to access your library to add a photo or videoo off kyc video </ string>
<key > NSPhotoLibraryUsageDescription </ key>
<string > Need to access your photo library to select a photo add and update profile picture </ string>
<key > NSContactsUsageDescription </ key>
<string > Need to access your contact </ string>

如果没有使用联系人功能,则请在 podfile 的末尾添加

post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == 'PayMESDK'
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] ||= '$(inherited)'
        config.build_settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] << 'IGNORE_CONTACT'
      end
    end
  end
end

SDK 使用方法

PayME 系统将为集成的应用程序提供以下信息

  • PublicKey:用于加密数据,应用程序整合需要传递给 SDK 以进行加密。
  • AppToken:由 AppId 独立定制的标识符,应用于每个应用程序,需要传递给 SDK 以进行加密。
  • SecretKey : 适用于在集成应用中,为后端系统加密和验证数据的密钥。

应用端将向 PayME 系统提供以下信息

  • AppPublicKey : 将通过 PayME 后端系统发送用于加密。 (不要传入 SDK 中)
  • AppPrivateKey : 将传入 PayME SDK 以执行解密操作。

加密标准:RSA-512bit。可以使用以下工具生成 在此处

初始化 PayME SDK

在使用 PayME SDK 之前,需要一次性调用初始化方法来初始化 SDK。

let payme = PayME(appToken: "AppToken",
  publicKey: "PublicKey",
  connectToken: "ConnectToken",
  appPrivateKey: "AppPrivateKey",
  language: PayME.Language.VIETNAMESE,
  configColor: ["#07A922"],
  env: PayME.Env.SANDBOX
)

其中参数如下

  • appPrivateKey: 是根据上述方式自生成的应用私钥

  • publicKey: 是 PayME 为每个应用提供的公钥。

  • configColor : 用于改变 PayME 钱包交易颜色的参数,数据类型为字符串,格式为

    rrggbb。如果传入 2 种颜色, PayME 的界面将根据传入的 2 种颜色渐变。

image

connectToken 的创建方法

connectToken 用于从 PayME 调用 API,并将由应用后端系统创建。其结构如下

connectToken = AES256("{ timestamp: "2021 - 01 - 20T06:53:07.621Z", 
userId: "ABC",
phone: "0909998877" }" 
  + secretKey )
参数 必填 解释
**
timestamp** 表示 connectToken 创建时间的时间戳,按照 iSO 8601 格式,用于确定 connectToken 的超时时间。例如 2021-01-20T06:53:07.621Z
***
userId*** 是每个客户的唯一值,通常由被集成系统的服务器提供。
***
phone*** 是集成系统的电话号码,如果系统不使用电话号码,可以不传或传 null。

其中 AES 是根据 AES 算法进行加密。根据服务器使用的编程语言,系统使用相应的库。更多信息请参阅此处

包含 KYC 信息 的 connectToken 的创建方法(适用于有 KYC 系统的合作伙伴)

// example 

connectToken = AES256("{
userId: "ABC",
phone: "0909998877",
timestamp: "2021-01-20T06:53:07.621Z",
kycInfo: {
  {
    fullname: "Nguyen Van A",
    gender: "MALE",
    birthday: "1995-01-20T06:53:07.621Z",
    address: "1 Nguyen Co Thach",
    identifyType: "CMND",
    identifyNumber: "123456789",
    issuedAt: "2012-01-20T06:53:07.621Z",
    placeOfIssue: "Hai Duong",
    video: "https://..../202/Co-29vnK6.mp4",
    face: "https://.../photo/2015/04/_480.jpg",
    image: {
    front: "https://.../photo/2015/04/_480.jpg",
    back: "https://.../photo/2015/04/_480.jpg",
  }
  }
}
}" + secretKey )

kycInfo 参数

参数 必填 解释
fullname 全名
gender 性别(MALE/FEMALE)
address 地址
identifyType 证件类型(CMND/CCCD)
identifyNumber 证件号
issuedAt 注册日期
placeOfIssue 颁发机构
video 视频链接
face 面部照片链接
front 证件正面照片链接
back 证件背面照片链接

PayME SDK 错误码

常量 错误码 解释
EXPIRED 401 token 已过期
DEACTIVATED_ACCOUNT 405 账户已被禁用
NETWORK -1 网络连接出错
SYSTEM -2 系统错误
LIMIT -3 余额不足,无法执行交易
ACCOUNT_NOT_ACTIVATED -4 错误:账户未激活
ACCOUNT_NOT_KYC -5 错误:账户未进行身份验证
PAYMENT_ERROR -6 支付失败
ERROR_KEY_ENCODE -7 错误:数据加密/解密失败
USER_CANCELLED -8 用户操作已取消
ACCOUNT_NOT_LOGIN -9 错误:未登录账户
PAYMENT_PENDING -11 支付正在处理中
ACCOUNT_ERROR -12 错误:账户被锁定

PayME SDK 功能

login()

包含两种情况

  • 用于在首次初始化 PayME 后进行登录。
  • accessToken 过期,调用 SDK 函数返回代码错误 ResponseCode.EXPIRED 或 ResponseCode.DEACTIVATED_ACCOUNT 时,此时 app 需要再次调用 login 以获取用于其他功能的 accessToken

成功调用 login() 后,才能调用 SDK 的其他功能(openWallet, pay 等)

public func login(
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

登录成功后,将返回一个包含以下信息的枚举 KYCState

public enum KYCState {
  case NOT_ACTIVATED
  case NOT_KYC
  case KYC_APPROVED
}

一些功能,如充值、提现、支付,只有在激活钱包并通过身份验证后才能执行。也就是说,登录将返回枚举 KYCState,其 case 为 KYC_APPROVED

logout()

public func logout()

用于从 SDK 会话中登出

close() - Đóng SDK

该函数用于在 pay()openWallet() 执行期间集成应用关闭 SDK 的 UI。

public func close() -> ()

openWallet() - Mở UI chức năng PayME tổng hợp

public func openWallet(
  currentVC: UIViewController,
  action: Action,
  amount: Int?,
  description: String?,
  extraData: String?,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

其中 enum Action 包含

  enum Action: String {
  case OPEN = "OPEN"
  case DEPOSIT = "DEPOSIT"
  case WITHDRAW = "WITHDRAW"
  case TRANSFER = "TRANSFER"
}

当应用集成调用 PayME 的一项功能时,会通过传入上面的 Action 参数来调用该函数。

参数

| 参数 | 必填 | 说明 | | :----------------------------------------------------------- | :----------- | : ----------------------------------------------------------- | | currentVC | 是 | PayME SDK 将据此打开 PayME 界面的 ViewController。 | | action | 是 |

  • OPEN : 用于打开 PayME WebView 界面,不执行任何特殊操作。
  • DEPOSIT: 用于打开 PayME 界面并执行 PayME 充值功能,PayME 将在界面显示成功或失败的消息。此外,如果需要,也会将结果返回给集成应用以便在应用中显示和处理。
  • WITHDRAW: 用于打开 PayME 界面并执行 PayME 提款功能,PayME 将在界面显示成功或失败的消息。此外,如果需要,也会将结果返回给集成应用以便在应用中显示和处理。
| | amount | 否 | 在 action 为 Deposit/Withdraw 时传入金额 | | description | 否 | 如果有,传入交易的描述 | | extraData | 否 | 在执行 Deposit 或 Withdraw 时,集成应用需要传递其他数据,以便 PayME 后端可以反向调用集成应用的后端。例如:交易的 transactionID 或应用集成所需的其他数据。 | | onSuccess | 是 | 用于捕获 PayME SDK 成功执行交易时的回调 | | onError | 是 | 用以捕获在调用 PayME SDK 过程中出现的错误 |

例子

import PayMESDK

class ViewController: UIViewController {
  let payME: PayME

  @IBAction func click(_ sender: Any) {
    payME.openWallet(
      currentVC: self,
      action: Action.OPEN,
      amount: nil,
      description: nil,
      extraData: nil
    )
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    payME = PayME(
      appID: appID,
      publicKey: self.PUBLIC_KEY,
      connectToken: self.connectToken,
      appPrivateKey: self.PRIVATE_KEY,
      env: currentEnv,
      configColor: ["#75255b", "#a81308"]
    )
  }
}

deposit() - Nạp tiền

public func deposit(
  currentVC: UIViewController,
  amount: Int?,
  description: String?,
  extraData: String?,
  closeWhenDone: Bool = false,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> () 

此函数的含义等同于调用 openWallet 并传入 Action.DEPOSIT 动作。

| 参数 | 默认值 | 说明 | | :----------------------------------------------------------- | :----------- | : ----------------------------------------------------------- | | closeWhenDone | false | true: 交易完成后关闭 SDK |

withdraw() - Rút tiền

public func withdraw(
  currentVC: UIViewController,
  amount: Int?,
  description: String?,
  extraData: String?,
  closeWhenDone: Bool = false,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

此函数的含义等同于调用 openWallet 并传入 Action.WITHDRAW 动作。

| 参数 | 默认值 | 说明 | | :----------------------------------------------------------- | :----------- | : ----------------------------------------------------------- | | closeWhenDone | false | true: 交易完成后关闭 SDK |

transfer() - Chuyển tiền

public func transfer(
  currentVC: UIViewController,
  amount: Int?,
  description: String?,
  extraData: String?,
  closeWhenDone: Bool = false,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

此函数的含义等同于调用 openWallet 并传入 Action.TRANSFER 动作。

| 参数 | 默认值 | 说明 | | :----------------------------------------------------------- | :----------- | : ----------------------------------------------------------- | | closeWhenDone | false | true: 交易完成后关闭 SDK |

openHistory() - Mở lịch sử giao dịch

public func openHistory(
  currentVC: UIViewController,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

此函数的含义等同于调用 openWallet 并传入 Action.OPEN_HISTORY 动作。

pay() - Thanh toán

当应用需要从激活的 PayME 钱包支付一笔钱时使用此函数。

⚠️版本 0.1.65 之前的版本

public func pay(
  currentVC: UIViewController,
  storeId: Int,
  orderId: Int,
  amount: Int,
  note: String?,
  paymentMethodID: Int?,
  extraData: String?,
  isShowResultUI: Bool = true,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

| 参数 | 必填 | 说明 | | : ----------------------------------------------------------- | :----------- | : ----------------------------------------------------------- | | currentVC | 是 | PayME SDK 依赖的 ViewController,用于打开 PayME 界面。 | | amount | 是 | 应用程序通过 SDK 传入的支付金额 | | extraData | 是 | 实施支付时,如果需要,应用程序应传入其他数据,以便 PayME 后端系统可以 IPN 回集成的后端系统。例如:交易 ID 或任何必要的数据。 | | storeId | 是 | 执行支付交易的收款方的 ID | | orderId | 是 | 对手的交易码,每个交易必须是唯一的(最多 22 个字符) | | note | 否 | 对手方的交易描述 | | isShowResultUI | 否 | 默认值为 true,表示在支付结果发生时将显示成功或失败界面。当传递值为 false 时,将不会显示成功或失败界面。 | | onSuccess | 是 | 成功时返回结果的回调 | | onError | 是 | 失败时返回结果的回调 |

若集成应用需要取余额以在 UI 上显示,则可使用 getWalletInfo% 函数,此函数不显示 PayME SDK 的 UI。

  • 使用 PayME 钱包支付时,需要已激活的账户,已验证的识别和钱包中的余额必须大于支付金额。
  • 通过 getAccountInfo% 函数获取账户信息。
  • 通过 getWalletInfo% 函数获取余额信息。

⚠️从版本 0.1.66 开始。

public func pay(
  currentVC: UIViewController,
  storeId: Int?,
  userName: String?,
  orderId: Int,
  amount: Int,
  note: String?,
  payCode: String,
  extraData: String?,
  isShowResultUI: Bool = true,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

| 参数 | 必填 | | | : ----------------------------------------------------------- | :----------- | : ----------------------------------------------------------- | | payCode | 是 | 支付方式列表 | | userName | 否 | 用户名 | | storeId | 否 | 执行交易的收款方的 ID |

注意:只有 userName 或 storeId,如果使用 userName,则将 storeId 设置为 nil,反之亦然。

scanQR() - 打开扫描 QR 码支付的功能

public func scanQR(
  currentVC: UIViewController,
  payCode: String,
  onSuccess: @escaping (Dictionary<String, AnyObject>) -> (),
  onError: @escaping (Dictionary<String, AnyObject>) -> ()
) -> ()

QR 码格式

let qrString = "{$type}|${storeId?}|${action}|${amount}|${note}|${orderId}|${userName?}"

例子

let qrString = "OPENEWALLET|54938607|PAYMENT|20000|Chuyentien|2445562323|DEMO)"
  • action: 交易类型('PAYMENT' => 支付)
  • amount: 支付金额
  • note: 对手方的交易描述
  • orderId: 对手的交易码,每个交易必须是唯一的
  • storeId: 执行交易的收款方的 ID
  • type: OPENEWALLET

payQRCode() - 使用 QR 码进行支付

public func payQRCode(
  currentVC: UIViewController,
  qr: String,
  payCode: String,
  isShowResultUI: Bool,
  onSuccess: @escaping (Dictionary<String, AnyObject>) -> (),
  onError: @escaping (Dictionary<String, AnyObject>) -> ()
) -> ()
  • qr: 进行支付用的 QR 码(格式与 scanQR% 函数相同)
  • isShowResultUI: 是否显示交易结果UI

openKYC() - 打开账户详情模态框

当集成应用需要打开账户详情模态框(要求账户尚未实名认证)时,此函数会被调用

public func openKYC(
  currentVC: UIViewController,
  onSuccess: ([Dictionary<String, AnyObject>]) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

getWalletInfo() - 获取钱包信息

public func getWalletInfo(
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()
  • 在出错情况下,此函数会在onError函数中返回错误信息,此时应用可以显示balance为0。

  • 在成功情况下,SDK会返回以下信息

{
  "walletBalance": {
    "balance": 111,
    "detail": {
      "cash": 1,
      "lockCash": 2
    }
  }
}

balance : 集成应用可以从中使用balance键值显示,其他字段目前尚未使用。

detail.cash : 可用金额

detail.lockCash: 锁定金额

getAccountInfo()

在SDK初始化完成后,应用可以使用此功能来获取与PayME钱包的连接状态。

public func getAccountInfo(
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

getSupportedServices()

用来确定SDK可以用来支付的服务(如电费、水费、学费等)。

public func getSupportedServices(
  onSuccess: ([ServiceConfig]) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()
class ServiceConfig {
...

  public func getCode() -> String

  public func getDescription() -> String

...
}

openService()

打开Web SDK进行服务支付

public func openService(
  currentVC: UIViewController,
  amount: Int?,
  description: String?,
  extraData: String?,
  service: ServiceConfig,
  onSuccess: (Dictionary<String, AnyObject>) -> (),
  onError: (Dictionary<String, AnyObject>) -> ()
) -> ()

setLanguage()

切换sdk的语言

public func setLanguage(language: PayME.Language) -> ()

getRemainingQuota()

获取支付交易限额

⚠️自版本0.9.57起

 public func getRemainingQuota(
  onSuccess: @escaping (Int) -> (),
  onError: @escaping (Dictionary<String, AnyObject>) -> ()
) -> ()

支付方式列表

payCode 支付方式
PAYME 将通过PayME钱包支付
ATM 国内ATM支付
MANUAL_BANK 银行转账支付
CREDIT 信用卡支付
VIET_QR 通过VietQR支付

备注

与use_framework!协同工作!