Mobile SDK Core
Това е по-скоро библиотека, отколкото SDK. Тя се използва за криптиране на данни от карта в seToken, който може безопасно да се предаде и съхрани във всяка система (например на сървър на търговец). Това е добро решение за търговци, които искат максимална гъвкавост или не искат да се занимават с данни от карти на своите сървъри.
Начини на плащане, поддържани от този SDK:
| Начин на плащане | Поддръжка |
|---|---|
| Банкова карта | Да |
| Запазени данни за достъп/карта | Да |
| Apple Pay | Не се изисква |
| Google Pay | Не се изисква |
Процес на плащане SDK Core
Web View за 3DS
На диаграмата по-долу е показан процесът на плащане SDK Core с пренасочване 3DS чрез Web View.
- Клиент създава поръчка
- Мобилен сървър регистрира тази поръчка в платежния шлюз чрез register.do. Използвайте параметър
returnUrlкато маркер за затваряне на Web View след пренасочване от ACS на Стъпка 14. - Мобилен сървър получава в отговора уникален номер на поръчка
mdOrder. - Клиент попълва платежни данни в мобилното приложение.
-
Мобилното приложение извиква SDK за създаване на seToken. (Android: sdkCore.generateWithCard; iOS: CKCToken.generateWithCard).
Публичният ключ, който се изисква в съответния метод, трябва да се взема от online ресурс https://uat.dskbank.bg/payment/se/keys.do. Ако по тази връзка са достъпни няколко ключа, трябва да се използва първият ключ. (Имайте предвид, че за тестова и работна среда се използват различни ключове.)
Мобилното приложение изпраща seToken на мобилния сървър.
-
Мобилен сървър използва този seToken за извършване на плащане чрез paymentorder.do.
- Използвайте seToken вместо pan, cvc и дата на изтичане на срока на валидност.
- Не забравяйте да укажете име на притежател на карта в поле
TEXT. Ако не събирате име на притежател на карта, просто изпратете стойностCARDHOLDER.
Мобилният сървър получава отговор без пренасочване към ACS. Това означава, че плащането е завършено и трябва да преминем към Стъпка 16.
Мобилният сървър получава отговор с пренасочване към ACS.
Мобилното приложение отваря Web View с данните за пренасочване към ACS.
Клиентът въвежда своята еднократна парола във формата на ACS.
ACS пренасочва клиента към платежната порта.
Платежната порта осъществява плащането.
Платежната порта пренасочва клиента към
returnUrl, което може да се използва като маркер за затваряне на Web View.Мобилното приложение затваря Web View.
Платежната порта изпраща известие за обратно повикване към сървъра на търговеца, ако е конфигурирано за търговеца.
Мобилният сървър проверява окончателния статус на плащането чрез getOrderStatusExtended.do.
Мобилното приложение показва резултата от плащането на клиента.
IOS
iOS-интеграция
Интеграция SDKCore.framework
Можете да интегрирате SDKCore.framework, като го добавите ръчно.
SDKCore.framework
Изтеглете най-новата версия на framework-а тук.
Изберете файла
SDKCore.frameworkи го добавете в папката на проекта.
- Отворете страницата Targets -> General -> Frameworks, Libraries, and Embedded Content. За
SDKCore.frameworkв колоната Embed заменетеDo not EmbedсEmbed & Sign.
След това импортирайте framework-а във файла
ViewController.swift .
//ViewController.swift
...
import SDKCore
...Работа с API V1
Външни зависимости
За генериране на токена е необходимо да се зададе публичният ключ.
let publicKey: String =
"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"Метод за генериране на токен
let sdkCore = SdkCore()
let cardParams = CardParams(
pan: "4111111111111111",
cvc: "123",
expiryMMYY: "12/28",
cardholder: "TEST CARDHOLDER",
mdOrder: "mdOrder",
pubKey: publicKey
)
let cardParamsConfig = SDKCoreConfig(
paymentMethodParams: .cardParams(params: cardParams)
)
let tokenResult = sdkCore.generateWithConfig(config: cardParamsConfig)
let bindignParams = BindingParams(
pubKey: publicKey,
bindingId: "das",
cvc: "123",
mdOrder: "mdOrder"
)
let bindingParamsConfig = SDKCoreConfig(
paymentMethodParams: .bindingParams(params: bindignParams)
)
let tokenResult = sdkCore.generateWithConfig(config: bindingParamsConfig)Модели
CardParams
| Название на свойството | Тип данни | Стойност по подразбиране | Незадължително | Описание |
|---|---|---|---|---|
| mdOrder | String | - | Не | Номер на поръчка |
| pan | String | - | Не | Номер на карта |
| cvc | String | - | Не | Секретен код на карта |
| expiryMMYY | String | - | Не | Срок на валидност на карта |
| cardHolder | String | - | Да | Име и фамилия на притежателя на карта |
| pubKey | String | - | Не | Публичен ключ |
BindingParams
| Название на свойството | Тип данни | Стойност по подразбиране | Незадължително | Описание |
|---|---|---|---|---|
| mdOrder | String | - | Не | Номер на поръчка |
| bindingId | String | - | Не | Номер на връзка за карта |
| cvc | String | - | Да | Секретен код на карта |
| pubKey | String | - | Не | Публичен ключ |
Грешки при валидация на полета
| ParamField | Грешка | Описание |
|---|---|---|
| UNKNOWN | - | Неизвестна грешка |
| PAN | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| invalid-format | Използват се недопустими символи. Достъпни са само цифри. | |
| CVC | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| EXPIRY | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| invalid-format | Форматът не съответства на шаблона MM/YY | |
| CARDHOLDER | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| invalid-format | Използват се недопустими символи. Достъпни са само букви и интервали. | |
| BINDING_ID | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| MD_ORDER | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| PUB_KEY | required | Посочено е празно поле |
Android
Android-интеграция
Свързване към Gradle проект чрез добавяне на .aar файлове на библиотеката
Необходимо е да добавите файла на библиотеката sdk_core-release.aar в папката libs, а след това да посочите зависимостта на добавената библиотека.
build.gradle.kts
allprojects {
repositories {
// ...
flatDir {
dirs("libs")
}
}
}
dependencies {
// dependency is mandatory to add
implementation(group = "", name = "sdk_core-release", ext = "aar")
}build.gradle
allprojects {
repositories {
// ...
flatDir {
dirs 'libs'
}
}
}
dependencies {
// dependency is mandatory to add
implementation(group: '', name: 'sdk_core-release', ext: 'aar')
}Конфигурация на Android
Логиране
Вътрешните процеси се логират с таг SDK-Core.
Можете също да логирате своите процеси.
Логирането е достъпно чрез обекта Logger.
-
За добавяне на log- интерфейси е необходимо да се извика
Logger-методаaddLogInterface().Пример за логиране в LogCat:
...
Logger.addLogInterface(object : LogInterface {
override fun log(classMethod: Class<Any>, tag: String, message: String, exception: Exception?) {
Log.i(tag, "$classMethod: $message", exception)
}
})
... По подразбиране се използва тагът SDK-Core. Можете да зададете свой собствен, ако искате.
-
За логиране на собствени събития е необходимо да се извика
Logger-методътlog().Пример:
...
Logger.log(this.javaClass, "MyTag", "My process...", null)
...Пример Kotlin_core (без графичен интерфейс)
Пример за формиране на криптограма
import net.payrdr.mobile.payment.sdk.core.SDKCore
import net.payrdr.mobile.payment.sdk.core.TokenResult
import net.payrdr.mobile.payment.sdk.core.model.BindingParams
import net.payrdr.mobile.payment.sdk.core.model.CardParams
import net.payrdr.mobile.payment.sdk.core.validation.BaseValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardCodeValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardExpiryValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardHolderValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardNumberValidator
import net.payrdr.mobile.payment.sdk.core.validation.OrderNumberValidator
class MainActivity : AppCompatActivity() {
// инициализация на валидатори за полетата за въвеждане на информация за карта
private val cardNumberValidator by lazy { CardNumberValidator(this) }
private val cardExpiryValidator by lazy { CardExpiryValidator(this) }
private val cardCodeValidator by lazy { CardCodeValidator(this) }
private val cardHolderValidator by lazy { CardHolderValidator(this) }
private val orderNumberValidator by lazy { OrderNumberValidator(this) }
private val sdkCore by lazy { SDKCore(context = this) }
override fun onCreate(savedInstanceState: Bundle?) {
// инсталиране на валидатори на полетата за въвеждане на информация за карта
cardNumberInput.setupValidator(cardNumberValidator)
cardExpiryInput.setupValidator(cardExpiryValidator)
cardCodeInput.setupValidator(cardCodeValidator)
cardHolderInput.setupValidator(cardHolderValidator)
mdOrderInput.setupValidator(orderNumberValidator)
// създаване на обект и инициализация на полета за нова карта
val params = NewPaymentMethodCardParams(
pan = cardNumberInput.text.toString(),
cvc = cardCodeInput.text.toString(),
expiryMMYY = cardExpiryInput.text.toString(),
cardHolder = cardHolderInput.text.toString(),
pubKey = pubKeyInput.text.toString()
)
// извикване на метод за получаване на криптограмата за нова карта
sdkCore.generateWithConfig(SDKCoreConfig(params))
// Създаване на обект и инициализация на полета за свързаната карта
val params = NewPaymentMethodStoredCardParams(
storedPaymentId = "storedPaymentMethodId",
cvc = "123",
pubKey = pubKeyInput.text.toString()
)
// method call to get the cryptogram for the linked card
sdkCore.generateWithConfig(SDKCoreConfig(params))
}
}Модели
NewPaymentMethodCardParams
| Название на свойството | Тип данни | Стойност по подразбиране | Незадължително | Описание |
|---|---|---|---|---|
| pan | String | - | Не | Номер на картата |
| cvc | String | - | Не | Секретен код на картата |
| expiryMMYY | String | - | Не | Срок на валидност на картата |
| cardHolder | String | - | Не | Име и фамилия на притежателя на картата |
| pubKey | String | - | Не | Публичен ключ |
NewPaymentMethodStoredCardParams
| Название на свойството | Тип данни | Стойност по подразбиране | Незадължително | Описание |
|---|---|---|---|---|
| storedPaymentId | String | - | Не | Номер на връзката за картата |
| cvc | String | - | Не | Секретен код на картата |
| pubKey | String | - | Не | Публичен ключ |
TokenResult
| Название на свойството | Тип данни | Стойност по подразбиране | Незадължително | Описание |
|---|---|---|---|---|
| token | String | - | Не | Токен като низ |
| errors | Map |
- | Не | Грешка при генериране на токен |
Грешки при валидация на полетата
| ParamField | Грешка | Описание |
|---|---|---|
| PAN | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| invalid-format | Използват се недопустими символи. Достъпни са само цифри. | |
| CVC | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| EXPIRY | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| invalid-format | Форматът не съответства на шаблона MM/YY. | |
| CARDHOLDER | required | Посочено е празно поле |
| invalid | Некоректна стойност | |
| invalid-format | Използват се недопустими символи. Достъпни са само букви и интервали. | |
| PUB_KEY | required | Посочено е празно поле |
| STORED_PAYMENT_ID | requrired | Посочено е празно поле |
| invalid | Некоректна стойност |
Работа с API V1
Външни зависимости
За генериране на токен е необходимо да се инсталира публичен ключ.
val publicKey: String =
"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"Метод за генериране на токен
// TokenResult with CardParams
val cardParams: CardParams = CardParams(
mdOrder = "mdOrder",
pan = "4111111111111111",
cvc = "123",
expiryMMYY = "12/28",
cardHolder = "TEST CARDHOLDER",
pubKey = "publicKey"
)
val tokenResult = sdkCore.generationWithConfig(paymentCardParams = cardParams)
// TokenResult with BindingParams
val bindingParams: BindingParams = BindingParams(
mdOrder = "mdOrder",
bindingID = "das",
cvc = "123",
pubKey = "publicKey"
)
val tokenResult = sdkCore.generationWithConfig(paymentCardParams = bindingParams)React Native
За реализация на интеграцията на Mobile SDK Core в React Native-приложение е необходимо да се настрои мост — обвивка на Kotlin/Java или Swift/Objective-C, която ще приема извиквания от JavaScript и ще ги предава в нативния код на SDK.
Мостовете в React Native позволяват на вашия JS-код да извиква методи на нативни библиотеки толкова просто, колкото обикновените асинхронни функции: вие декларирате нативен модул с методи, които връщат резултат чрез Promise, React Native автоматично свързва тези методи с JavaScript, и след това работите с тях в приложението без задълбочени знания за платформените API.
IOS
Интегрирайте SDKCore във вашия проект в съответствие с раздела iOS-интеграция.
Проверете, че за фреймуорка
SDKCore.xcframeworkв колоната Embed е избрано Embed & Sign.-
Създайте Swift-модул
RadarSdkBridge.swiftсъс следното съдържание:import Foundation import React import SDKCore @objc(RadarSdk) class RadarSdkBridge: NSObject { private let sdkCore = SdkCore() @objc func generateNewCardToken( _ pan: String, cvc: String, expiryMMYY: String, cardHolder: String, mdOrder: String, pubKey: String, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock ) { do { let params = CardParams( pan: pan, cvc: cvc, expiryMMYY: expiryMMYY, cardholder: cardHolder, mdOrder: mdOrder, pubKey: pubKey ) let config = SDKCoreConfig(paymentMethodParams: .cardParams(params: params)) let result = try sdkCore.generateWithConfig(config: config) resolve(result.token) } catch { reject("TOKEN_ERROR", error.localizedDescription, error) } } @objc func generateStoredCardToken( _ storedPaymentId: String, cvc: String, pubKey: String, mdOrder: String, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock ) { do { let params = BindingParams( pubKey: pubKey, bindingId: storedPaymentId, cvc: cvc, mdOrder: mdOrder ) let config = SDKCoreConfig(paymentMethodParams: .bindingParams(params: params)) let result = try sdkCore.generateWithConfig(config: config) resolve(result.token) } catch { reject("TOKEN_ERROR", error.localizedDescription, error) } } @objc static func requiresMainQueueSetup() -> Bool { return false } } -
Реализирайте Objective-C мост във файла
RadarSdkBridge.m:#import <React/RCTBridgeModule.h> @interface RCT_EXTERN_MODULE(RadarSdk, NSObject) RCT_EXTERN_METHOD(generateNewCardToken: (NSString *)pan cvc:(NSString *)cvc expiryMMYY:(NSString *)expiryMMYY cardHolder:(NSString *)cardHolder mdOrder:(NSString *)mdOrder pubKey:(NSString *)pubKey resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject ) RCT_EXTERN_METHOD(generateStoredCardToken: (NSString *)storedPaymentId cvc:(NSString *)cvc pubKey:(NSString *)pubKey mdOrder:(NSString *)mdOrder resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject ) @end
Android
Изтеглете файловете
sdk_core-release.aarиsdk_logs-release.aarи ги копирайте в папкатаandroid/app/libs/съгласно раздела Android-интеграция.-
Добавете плосък репозиторий и зависимости във файла
android/app/build.gradle:android { // … останалата конфигурация на вашия проект … } repositories { flatDir { dirs 'libs' } } dependencies { // … други зависимости … implementation(name: 'sdk_core-release', ext: 'aar') implementation(name: 'sdk_logs-release', ext: 'aar') }
Реализация на Native Module за Kotlin
-
Създайте файл
RadarSdkModule.ktв директориятаandroid/app/src/main/java/.../radar/:package com.mobilesdkdemo.radar import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import net.payrdr.mobile.payment.sdk.core.SDKCore import net.payrdr.mobile.payment.sdk.core.model.SDKCoreConfig import net.payrdr.mobile.payment.sdk.core.model.CardParams import net.payrdr.mobile.payment.sdk.core.model.BindingParams class RadarSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { override fun getName(): String = "RadarSdk" private val sdkCore by lazy { SDKCore(context = reactApplicationContext) } @ReactMethod fun generateNewCardToken( pan: String, cvc: String, expiryMMYY: String, cardHolder: String, mdOrder: String, pubKey: String, promise: Promise ) { try { val params = CardParams( pan = pan, cvc = cvc, expiryMMYY = expiryMMYY, cardHolder = cardHolder, mdOrder = mdOrder, pubKey = pubKey ) val config = SDKCoreConfig(paymentCardParams = params) val result = sdkCore.generateWithConfig(config) promise.resolve(result.token) } catch (e: Exception) { promise.reject("TOKEN_ERROR", e) } } @ReactMethod fun generateStoredCardToken( storedPaymentId: String, cvc: String, pubKey: String, mdOrder: String, promise: Promise ) { try { val params = BindingParams( bindingID = storedPaymentId, mdOrder = mdOrder, cvc = cvc, pubKey = pubKey ) val config = SDKCoreConfig(paymentCardParams = params) val result = sdkCore.generateWithConfig(config) promise.resolve(result.token) } catch (e: Exception) { promise.reject("TOKEN_ERROR", e) } } } -
Създайте пакет
RadarSdkPackage.ktв същата директория:package com.mobilesdkdemo.radar import com.facebook.react.ReactPackage import com.facebook.react.bridge.NativeModule import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.uimanager.ViewManager class RadarSdkPackage : ReactPackage { override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = listOf(RadarSdkModule(reactContext)) override fun createViewManagers( reactContext: ReactApplicationContext ): List<ViewManager<*, *>> = emptyList() } -
Регистрирайте създадения пакет в
MainApplication.kt:package com.mobilesdkdemo import android.app.Application import com.facebook.react.PackageList import com.facebook.react.ReactApplication import com.facebook.react.ReactNativeHost import com.facebook.react.ReactHost import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load import com.facebook.react.defaults.DefaultReactNativeHost import com.facebook.soloader.SoLoader import com.mobilesdkdemo.radar.RadarSdkPackage class MainApplication : Application(), ReactApplication { override val reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) { override fun getPackages(): List<ReactPackage> = PackageList(this).packages.apply { add(RadarSdkPackage()) // Регистрираме пакета } override fun getJSMainModuleName(): String = "index" override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED } override val reactHost: ReactHost get() = getReactNativeHost(applicationContext, reactNativeHost) override fun onCreate() { super.onCreate() SoLoader.init(this, false) if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { load() } } }
Използване в React Native
Използвайте методите от JavaScript/TypeScript по следния начин:
import { NativeModules } from 'react-native';
const { RadarSdk } = NativeModules;
// Генериране на токен за нова карта
const token = await RadarSdk.generateNewCardToken(
'4111111111111111', // PAN
'123', // CVC
'12/25', // Expiry MM/YY
'CARDHOLDER NAME', // Име на притежателя на картата
'mdOrder', // Номер, получен при регистрация на поръчката
'-----BEGIN PUBLIC KEY-----...' // Публичен ключ от /payment/se/keys.do
);
// Генериране на токен за свързана карта
const bindToken = await RadarSdk.generateStoredCardToken(
'bindingId', // ID на запазената карта
'123', // CVC
'-----BEGIN PUBLIC KEY-----…', // Публичен ключ от /payment/se/keys.do
'mdOrder' // Номер, получен при регистрация на поръчката
);
Демо приложение
Пример за интегриране на Mobile Sdk Core в приложение на React Native можете да видите в GitHub.
Mobile SDK Source
iOS
Изисквания: iOS 10.0 или по-висока версия
Android
Android изходни кодове в GitHub
Изисквания: Android 5.0 или по-висока версия