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
Изтеглете последната версия на фреймуорка тук.
Изберете файла
SDKCore.frameworkи го добавете в папката на проекта.
- Отворете страницата Targets -> General -> Frameworks, Libraries, and Embedded Content. За
SDKCore.frameworkв колоната Embed заменетеDo not EmbedсEmbed & Sign.
След това импортирайте фреймуорка във файла
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() {
// initialization of validators for card information entry fields
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()
)
// извикване на метод за получаване на криптограма за свързаната карта
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 | - | Не | Token като низ |
| errors | Map |
- | Не | Грешка при генериране на token |
Грешки при валидация на полетата
| 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
Външни зависимости
За генериране на token е необходимо да се инсталира публичният ключ.
val publicKey: String =
"-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"Метод за генериране на token
// 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 или по-висока версия