- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为 Paytm 创建一个插件,并为 Android 和 iOS 编写平台特定代码。
Paytm 是印度的支付网关服务,配置和集成到应用程序中非常容易。它需要一些配置,最后一步是启动支付交易,该交易在 Android 上内部打开自己的 Activity,在 iOS 平台上打开 ViewController。
我测试了该插件的 Android 部分。运行良好。
但我不知道如何在 iOS 中触发 viewController。我正在使用 swift 进行 iOS 编码部分。
func beginPayment() {
serv = serv.createProductionEnvironment()
let type :ServerType = .eServerTypeProduction
let order = PGOrder(orderID: "", customerID: "", amount: "", eMail: "", mobile: "")
order.params = [
"MID": "rxazcv89315285244163",
"ORDER_ID": "order1",
"CUST_ID": "cust123",
"MOBILE_NO": "7777777777",
"EMAIL": "username@emailprovider.com",
"CHANNEL_ID": "WAP",
"WEBSITE": "WEBSTAGING",
"TXN_AMOUNT": "100.12",
"INDUSTRY_TYPE_ID": "Retail",
"CHECKSUMHASH": "oCDBVF+hvVb68JvzbKI40TOtcxlNjMdixi9FnRSh80Ub7XfjvgNr9NrfrOCPLmt65UhStCkrDnlYkclz1qE0uBMOrmuKLGlybuErulbLYSQ=",
"CALLBACK_URL": "https://securegw-stage.paytm.in/theia/paytmCallback?ORDER_ID=order1"
]
self.txnController = self.txnController.initTransaction(for: order) as?PGTransactionViewController
self.txnController.title = "Paytm Payments" self.txnController.setLoggingEnabled(true)
if(type != ServerType.eServerTypeNone) {
self.txnController.serverType = type;
} else { return }
self.txnController.merchant = PGMerchantConfiguration.defaultConfiguration()
self.txnController.delegate = self
self.navigationController?.pushViewController(self.txnController, animated: true) }
这是有关如何触发 PayTM iOS SDK 文档页面中编写的 Paytm 交易 Controller 的演示。
这是我为实现上述过程而编写的代码。
import Flutter
import PaymentSDK
import UIKit
/*
A delegate interface that exposes all of the PayTM Payment Gateway functionality for other plugins to use.
The below [Delegate] implementation should be used by any clients unless they need to
override some of these functions, such as for testing.
*/
protocol IDelegate {
// Initializes this delegate so that it can perform transaction operation
func initializePaytmService(result: @escaping FlutterResult, buildVariant: String?)
// Returns the PayTM transaction status without displaying any user interface.
func startPaymentTransaction(result: @escaping FlutterResult, checkSumRequestObject: Dictionary<String, String>?)
}
/*
Delegate class will have the code for making PayTM Transactions.
*/
class FlutterPaytmPluginDelegate : IDelegate, PGTransactionDelegate {
private let flutterRegistrar: FlutterPluginRegistrar
private var viewController: UIViewController
private var serverType: ServerType?
private var pendingOperation: PendingOperation?
private var paytmTransactionController: PGTransactionViewController?
let release = "BuildVariant.release"
let debug = "BuildVariant.debug"
//Method Constants
let methodInitPaytmService = "initialize_paytm_service"
let methodStartPaymentTransaction = "start_payment_transaction"
//PayTM Success Response Constants
let paytmStatus = "STATUS"
let paytmChecksumHash = "CHECKSUMHASH"
let paytmBankName = "BANKNAME"
let paytmOrderId = "ORDERID"
let paytmTransactionAmount = "TXNAMOUNT"
let paytmTransactionDate = "TXNDATE"
let paytmMerchantId = "MID"
let paytmTransactionId = "TXNID"
let paytmResponseCode = "RESPCODE"
let paytmPaymentMode = "PAYMENTMODE"
let paytmBankTransactionId = "BANKTXNID"
let paytmCurrency = "CURRENCY"
let paytmGatewayName = "GATEWAYNAME"
let paytmResponseMessage = "RESPMSG"
//Error Constants
let errorReasonBuildVariantNotPassed = "build_variant_not_passed"
let errorReasonChecksumObjectNotPassed = "checksum_request_object_not_passed"
// These error codes must match with ones declared on iOS and Dart sides.
let errorReasonPaytmTransactionResponseNull = "paytm_transaction_response_null"
let errorReasonPaytmTransactionCancelled = "paytm_transaction_cancelled"
let errorReasonPaytmMissingParameters = "paytm_missing_parameters"
init(registrar: FlutterPluginRegistrar, viewController: UIViewController) {
self.flutterRegistrar = registrar
self.viewController = viewController
}
/*
Initializes this delegate so that it is ready to perform other operations. The Dart code
guarantees that this will be called and completed before any other methods are invoked.
*/
func initializePaytmService(result: @escaping FlutterResult, buildVariant: String?) {
if buildVariant?.isEmpty ?? true {
result(FlutterError(code: errorReasonBuildVariantNotPassed, message: "Need a build variant", details: nil))
} else {
serverType = buildVariant == release ? .eServerTypeProduction : .eServerTypeStaging
result(nil)
}
}
func startPaymentTransaction(result: @escaping FlutterResult, checkSumRequestObject: Dictionary<String, String>?) {
if checkSumRequestObject?.isEmpty ?? true {
result(FlutterError(code: errorReasonChecksumObjectNotPassed, message: "Need a build variant", details: nil))
} else {
checkAndSetPendingOperation(method: methodStartPaymentTransaction, result: result)
let order = PGOrder(orderID: "", customerID: "", amount: "", eMail: "", mobile: "")
order.params = checkSumRequestObject!
self.paytmTransactionController = paytmTransactionController?.initTransaction(for: order) as? PGTransactionViewController ?? PGTransactionViewController()
self.paytmTransactionController?.title = "Paytm Payments"
if(serverType != .eServerTypeNone) {
self.paytmTransactionController?.serverType = serverType;
} else {
return
}
self.paytmTransactionController?.setLoggingEnabled(serverType == .eServerTypeStaging)
self.paytmTransactionController?.merchant = PGMerchantConfiguration.defaultConfiguration()
self.paytmTransactionController?.delegate = self
UIApplication.shared.delegate?.window??.rootViewController?.present(paytmTransactionController, animated: true, completion: nil)
}
}
private func checkAndSetPendingOperation(method: String, result: @escaping FlutterResult) {
if (pendingOperation != nil) {
return;
// throw IllegalStateException("Concurrent operations detected: " + pendingOperation!!.method + ", " + method)
}
pendingOperation = PendingOperation(method: method, result: result)
}
private func finishWithSuccess(data: Dictionary<String, String>?) {
pendingOperation!.result(data)
pendingOperation = nil
paytmTransactionController = nil
}
private func finishWithError(errorCode: String, errorMessage: String) {
pendingOperation!.result(FlutterError(code: errorCode, message: errorMessage, details: nil))
pendingOperation = nil
}
/*
PayTM Transaction Delegates
*/
func didFinishedResponse(_ controller: PGTransactionViewController, response responseString: String) {
var paytmSuccessResponse = Dictionary<String, String>()
if let data = responseString.data(using: String.Encoding.utf8) {
do {
if let jsonresponse = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:String] , jsonresponse.count > 0{
paytmSuccessResponse[paytmStatus] = jsonresponse[paytmStatus] ?? ""
paytmSuccessResponse[paytmChecksumHash] = jsonresponse[paytmChecksumHash] ?? ""
paytmSuccessResponse[paytmBankName] = jsonresponse[paytmBankName] ?? ""
paytmSuccessResponse[paytmOrderId] = jsonresponse[paytmOrderId] ?? ""
paytmSuccessResponse[paytmTransactionAmount] = jsonresponse[paytmTransactionAmount] ?? ""
paytmSuccessResponse[paytmTransactionDate] = jsonresponse[paytmTransactionDate] ?? ""
paytmSuccessResponse[paytmTransactionId] = jsonresponse[paytmTransactionId] ?? ""
paytmSuccessResponse[paytmMerchantId] = jsonresponse[paytmMerchantId] ?? ""
paytmSuccessResponse[paytmResponseCode] = jsonresponse[paytmResponseCode] ?? ""
paytmSuccessResponse[paytmPaymentMode] = jsonresponse[paytmPaymentMode] ?? ""
paytmSuccessResponse[paytmBankTransactionId] = jsonresponse[paytmBankTransactionId] ?? ""
paytmSuccessResponse[paytmCurrency] = jsonresponse[paytmCurrency] ?? ""
paytmSuccessResponse[paytmGatewayName] = jsonresponse[paytmGatewayName] ?? ""
paytmSuccessResponse[paytmResponseMessage] = jsonresponse[paytmResponseMessage] ?? ""
finishWithSuccess(data: paytmSuccessResponse)
}
} catch {
finishWithError(errorCode: errorReasonPaytmTransactionResponseNull, errorMessage: "Paytm transaction response in null")
}
}
}
func didCancelTrasaction(_ controller: PGTransactionViewController) {
finishWithError(errorCode: errorReasonPaytmTransactionCancelled, errorMessage: "Transaction cancelled.")
}
func errorMisssingParameter(_ controller: PGTransactionViewController, error: NSError?) {
finishWithError(errorCode: errorReasonPaytmMissingParameters, errorMessage: "There are some missing parameters.")
}
private class PendingOperation {
let method: String
let result: FlutterResult
init(method: String, result: @escaping FlutterResult) {
self.method = method
self.result = result
}
}
}
public class SwiftFlutterPaytmPlugin: NSObject, FlutterPlugin {
//Channel Name Constant
static let channelName = "flutterpaytmplugin.flutter.com/flutter_paytm_plugin"
//Argument Constants
let buildVariant = "build_variant"
let checksumRequestObject = "checksum_request_object"
//Method Constants
let methodInitPaytmService = "initialize_paytm_service"
let methodStartPaymentTransaction = "start_payment_transaction"
var delegate : IDelegate
init(pluginRegistrar: FlutterPluginRegistrar, uiViewController: UIViewController) {
delegate = FlutterPaytmPluginDelegate(registrar: pluginRegistrar, viewController: uiViewController)
}
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
let viewController: UIViewController =
(UIApplication.shared.delegate?.window??.rootViewController)!;
let instance = SwiftFlutterPaytmPlugin(pluginRegistrar: registrar, uiViewController: viewController)
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
let arguments = call.arguments as? Dictionary<String, Any>
switch call.method {
case methodInitPaytmService:
delegate.initializePaytmService(result: result, buildVariant: (arguments?[buildVariant] as? String))
case methodStartPaymentTransaction:
delegate.startPaymentTransaction(result: result, checkSumRequestObject: (arguments?[checksumRequestObject] as? Dictionary<String, String>))
default:
result(FlutterMethodNotImplemented)
}
}
}
我正在遵循此已关闭问题 https://github.com/flutter/flutter/issues/9961 中的一些建议.
但找不到成功。
这是我得到的日志跟踪:
2018-12-07 17:27:39.510397+0530 Runner[56634:1432738] You've implemented -[<UIApplicationDelegate> application:performFetchWithCompletionHandler:], but you still need to add "fetch" to the list of your supported UIBackgroundModes in your Info.plist.
2018-12-07 17:27:39.510615+0530 Runner[56634:1432738] You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist.
2018-12-07 17:27:39.610121+0530 Runner[56634:1432850] flutter: Observatory listening on http://127.0.0.1:56923/
PGTransactionViewController:loadView
PGTransactionViewController::viewDidLoad
PGTransactionViewController::viewWillAppear
(lldb)
有一个异常(exception): Exception showcased in the image
请帮帮我。
最佳答案
我的一个 friend @virander帮助我解决了这个问题。他编写了从 swift 插件文件打开 View Controller 的代码。
if let navigationController = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController {
navigationController.pushViewController(self.paytmTransactionController!, animated: true)
}
let storyboard : UIStoryboard? = UIStoryboard.init(name: "Main", bundle: nil);
let window: UIWindow = ((UIApplication.shared.delegate?.window)!)!
let objVC: UIViewController? = storyboard!.instantiateViewController(withIdentifier: "FlutterViewController")
let aObjNavi = UINavigationController(rootViewController: objVC!)
window.rootViewController = aObjNavi
aObjNavi.pushViewController(self.paytmTransactionController!, animated: true)
使用此代码,我可以从 Swift 插件类触发 PayTM View Controller 。
关于ios - 如何从 Flutter 平台启动 ViewController 特定于 Swift 编写的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53652759/
我只想从客户端向服务器发送数组 adc_array=[w, x, y, z]。下面是客户端代码,而我的服务器是在只接受 json 的 python 中。编译代码时我没有收到任何错误,但收到 2 条警告
我是 lua 和 Node js 的新手,我正在尝试将我正在开发的移动应用程序连接到服务器。问题是它连接到服务器,但我尝试传递的数据丢失或无法到达服务器。对我正在做的事情有什么问题有什么想法吗? th
我在这个页面上工作 http://www.haskell.org/haskellwiki/99_questions/Solutions/4 我理解每个函数的含义,看到一个函数可以像这样以多种方式定义,
我目前正在尝试将数据写入 excel 以生成报告。我可以将数据写入 csv 文件,但它不会按照我想要的顺序出现在 excel 中。我需要数据在每列的最佳和最差适应性下打印,而不是全部打印在平均值下。这
所以,我正在做一个项目,现在我有一个问题,所以我想得到你的帮助:) 首先,我已经知道如何编写和读取 .txt 文件,但我想要的不仅仅是 x.hasNext()。 我想知道如何像 .ini 那样编写、读
我正在尝试编写一个函数,该函数将返回作为输入给出的任何数字的阶乘。现在,我的代码绝对是一团糟。请帮忙。 function factorialize(num) { for (var i=num, i
这个问题已经有答案了: Check variable equality against a list of values (16 个回答) 已关闭 4 年前。 有没有一种简洁或更好的方法来编写这个条件
我对 VR 完全陌生,正在 AFrame 中为一个类(class)项目开发 VR 太空射击游戏,并且想知道 AFrame 中是否有 TDD 的任何文档/标准。有人能指出我正确的方向吗? 最佳答案 几乎
我正在尝试创建一个 for 循环,它将重现以下功能代码块,但以一种更具吸引力的方式。这是与 Soundcould 小部件 API 实现一起使用的 here on stackoverflow $(doc
我有一个非常令人困惑的问题。我正在尝试更改属性文件中的属性,但它只是没有更改... 这是代码: package config; import java.io.FileNotFoundException
我对 VR 完全陌生,正在 AFrame 中为一个类(class)项目开发 VR 太空射击游戏,并且想知道 AFrame 中是否有 TDD 的任何文档/标准。有人能指出我正确的方向吗? 最佳答案 几乎
我正在开发一个用户模式(Ring3)代码级调试器。它还应支持.NET可执行文件的本机(x86)调试。基本上,我需要执行以下操作: 1).NET在隐身模式下加载某些模块,而没有LOAD_DLL_DEBU
我有一个列表,我知道有些项目是不必要打印的,我正在尝试通过 if 语句来做到这一点...但是它变得非常复杂,所以有没有什么方法可以在 if 语句中包含多个索引而无需打印重写整个声明。 看起来像这样的东
我很好奇以不同方式编写 if 语句是否会影响程序的速度和效率。所以,例如写一个这样的: bool isActive = true; bool isResponding = false; if (isA
我在搜索网站的源代码时找到了一种以另一种方式(我认为)编写 if 语句的方法。 代替: if(a)b; 或: a?b:''; 我读了: !a||b; 第三种方式和前两种方式一样吗?如果是,为什么我们要
我的数据采用以下格式(HashMap的列表) {TeamName=India, Name=Sachin, Score=170} {TeamName=India, Name=Sehwag, Score=
我目前正在完成 More JOIN operations sqlzoo 的教程,遇到了下面的代码作为#12 的答案: SELECT yr,COUNT(title) FROM movie JOIN ca
我正试图找到一种更好的方法来编写这段代码: def down_up(array, player) 7.downto(3).each do |row| 8.times do |col
出于某种原因,我的缓冲区中充满了乱码,我不确定为什么。我什至用十六进制编辑器检查了我的文件,以验证我的字符是否以 2 字节的 unicode 格式保存。我不确定出了什么问题。 [打开文件] fseek
阅读编码恐怖片时,我刚刚又遇到了 FizzBuzz。 原帖在这里:Coding Horror: Why Can't Programmers.. Program? 对于那些不知道的人:FizzBu
我是一名优秀的程序员,十分优秀!