feat(ios): fix bugs in ios; complete implementation

pull/2/merge
codinronan 5 years ago
parent e6522e4154
commit 37e9065ad6

@ -54,22 +54,25 @@
</feature>
</config-file>
<!-- <framework src="Stripe" type="podspec" spec="~> 15.0.0" />
<framework src="Stripe" type="podspec" spec="~> 15.0.0" />
<framework src="Alamofire" type="podspec" spec="~> 4.8.1" />
<framework src="CardIO" type="podspec" spec="~> 5.4.1" /> -->
<framework src="CardIO" type="podspec" spec="~> 5.4.1" />
<!-- https://github.com/cordova-develop/cordova-plugin-pods3/blob/master/plugin.xml -->
<pods use-frameworks="true">
<pod name="Stripe" spec="~> 15.0.0" />
<pod name="CardIO" spec="~> 5.4.1" />
<pod name="Alamofire" spec="~> 4.8.1" />
</pods>
<!-- <podspec>
<config>
<source url="https://github.com/CocoaPods/Specs.git"/>
</config>
<pods use-frameworks="true">
<pod name="Stripe" spec="~> 15.0.0" />
<pod name="CardIO" spec="~> 5.4.1" />
<pod name="Alamofire" spec="~> 4.8.1" swift-version="4.2" />
</pods>
</podspec> -->
<source-file src="src/ios/StripeAPIClient.swift" />
<source-file src="src/ios/StripePaymentOptions.swift" />
<source-file src="src/ios/StripePaymentsPluginConfig.swift" />
<source-file src="src/ios/StripePaymentsPlugin.swift" />
<!-- <framework src="Foundation.framework" /> -->
</platform>
</plugin>

@ -22,20 +22,26 @@ class StripeAPIClient: NSObject, STPCustomerEphemeralKeyProvider {
}
let parameters: [String: Any] = ["api_version": apiVersion]
let headers: HTTPHeaders = [
var headers: HTTPHeaders = [
// "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
// TODO need xcode for this.
// Assign any extra headers we've been provided. We COULD use Alamofire's custom auth header types,
// but that would require tracking & strongly typing the headers we pass from the app. Too much
// work that is not really necessary.
if PluginConfig.extraHTTPHeaders.count > 0 {
// for each HTTPHeader in extraHTTPHeaders
// headers.add(header)
for key: String in PluginConfig.extraHTTPHeaders.keys {
headers[key] = PluginConfig.extraHTTPHeaders[key]
}
}
print("[StripePaymentsPlugin](StripeAPIClient).createCustomerKey: requesting key from \(url) with headers: \(headers)")
Alamofire.request(url, method: .post, parameters: parameters, headers: headers)
.validate(statusCode: 200..<300)
.responseJSON { responseJSON in
print("[StripePaymentsPlugin](StripeAPIClient).createCustomerKey: got server result: \(responseJSON)")
switch responseJSON.result {
case .success(let json):
guard let data = json as? [String: AnyObject] else {
@ -54,5 +60,4 @@ class StripeAPIClient: NSObject, STPCustomerEphemeralKeyProvider {
// completion(json, nil)
}
}
}

@ -15,6 +15,7 @@ import Stripe
private var paymentStatusCallback: String = ""
private var customerContext: STPCustomerContext!
private var paymentContext: STPPaymentContext!
private var keyRetries: Int = 0
override func pluginInitialize() {
super.pluginInitialize()
@ -23,6 +24,11 @@ import Stripe
@objc(addPaymentStatusObserver:)
func addPaymentStatusObserver(command: CDVInvokedUrlCommand) {
paymentStatusCallback = command.callbackId
let resultMsg = [
"status": "LISTENER_ADDED"
]
successCallback(paymentStatusCallback, resultMsg, keepCallback: true)
}
// MARK: Init Method
@ -43,10 +49,10 @@ import Stripe
PluginConfig.ephemeralKeyUrl = dict["ephemeralKeyUrl"] as? String ?? ""
PluginConfig.appleMerchantId = dict["appleMerchantId"] as? String ?? ""
PluginConfig.companyName = dict["companyName"] as? String ?? ""
PluginConfig.requestPaymentImmediately = dict["requestPaymentImmediately"] as? Bool ?? true
PluginConfig.maximumKeyRetries = dict["maximumKeyRetries"] as? Int ?? 0
if let headersDict = dict["extraHTTPHeaders"] as? [String:String] {
PluginConfig.parseExtraHeaders(dict: headersDict)
PluginConfig.extraHTTPHeaders = headersDict
}
if !self.verifyConfig() {
@ -62,13 +68,19 @@ import Stripe
STPPaymentConfiguration.shared().appleMerchantIdentifier = PluginConfig.appleMerchantId
}
customerContext = STPCustomerContext(keyProvider: StripeAPIClient.shared)
paymentContext = STPPaymentContext(customerContext: customerContext)
successCallback(command.callbackId, [ "status": "INIT_SUCCESS" ])
}
paymentContext.delegate = self
paymentContext.hostViewController = self.viewController
func createPaymentContext() {
if (customerContext == nil || paymentContext == nil) {
customerContext = STPCustomerContext(keyProvider: StripeAPIClient.shared)
paymentContext = STPPaymentContext(customerContext: customerContext)
successCallback(command.callbackId, [ "status": "INIT_SUCCESS" ])
paymentContext.delegate = self
paymentContext.hostViewController = self.viewController
}
customerContext.clearCachedCustomer()
}
@ -90,17 +102,18 @@ import Stripe
return
}
let paymentOptions = PaymentOptions(dict: options)
paymentContext.paymentAmount = paymentOptions.price
paymentContext.paymentCurrency = paymentOptions.currency
paymentContext.paymentCountry = paymentOptions.country
// Allow these to be overridden
PluginConfig.requestPaymentImmediately = options["requestPaymentImmediately"] as? Bool ?? PluginConfig.requestPaymentImmediately
if let headersDict = options["extraHTTPHeaders"] as? [String:String] {
PluginConfig.parseExtraHeaders(dict: headersDict)
PluginConfig.extraHTTPHeaders = headersDict
}
createPaymentContext()
let paymentOptions = StripePaymentOptions(dict: options)
paymentContext.paymentAmount = paymentOptions.price
paymentContext.paymentCurrency = paymentOptions.currency
paymentContext.paymentCountry = paymentOptions.country
// This dialog collects a payment method from the user. When they close it, you get a context
// change event with the payment info. NO charge has been created at that point, NO source
// has been created from the payment method. All that has happened is the user entered
@ -120,12 +133,19 @@ import Stripe
return
}
if (paymentContext == nil || customerContext == nil) {
let error = "[CONFIG]: Config is not set, init() must be called before using plugin"
errorCallback(command.callbackId, [ "status": "REQUEST_PAYMENT_ERROR", "error": error ])
return
}
doRequestPayment(command.callbackId)
}
func doRequestPayment(_ callbackId: String) {
keyRetries = 0
successCallback(callbackId, [ "status": "REQUEST_PAYMENT_STARTED" ], keepCallback: true)
paymentContext.requestPayment()
successCallback(callbackId, [ "status": "REQUEST_PAYMENT_STARTED" ])
}
@ -153,19 +173,24 @@ import Stripe
}
print(callbackMessage)
errorCallback(paymentStatusCallback, ["error": callbackMessage], keepCallback: true)
let alertController = UIAlertController(
title: "",
message: message,
preferredStyle: .alert
)
let retry = UIAlertAction(title: "Retry", style: .default, handler: { (action) in
// Retry payment context loading
self.paymentContext.retryLoading()
})
alertController.addAction(retry)
self.viewController.present(alertController, animated: true, completion: nil)
if (keyRetries < PluginConfig.maximumKeyRetries) {
keyRetries += 1
let alertController = UIAlertController(
title: "",
message: message,
preferredStyle: .alert
)
let retry = UIAlertAction(title: "Retry", style: .default, handler: { (action) in
// Retry payment context loading
self.paymentContext.retryLoading()
})
alertController.addAction(retry)
self.viewController.present(alertController, animated: true, completion: nil)
} else {
errorCallback(paymentStatusCallback, ["error": callbackMessage], keepCallback: true)
}
}
func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
@ -197,11 +222,8 @@ import Stripe
"image": image
]
print("[StripePaymentsPlugin].paymentContextDidChange: \(resultMsg)")
successCallback(paymentStatusCallback, resultMsg, keepCallback: true)
if isPaymentReady && PluginConfig.requestPaymentImmediately {
doRequestPayment(paymentStatusCallback)
}
}
// This callback is triggered when requestPayment() completes successfully to create a Source.
@ -213,6 +235,7 @@ import Stripe
"source": paymentResult.source.stripeID
]
print("[StripePaymentsPlugin].paymentContext.didCreatePaymentResult: \(resultMsg)")
successCallback(paymentStatusCallback, resultMsg, keepCallback: true)
completion(nil)
}
@ -242,12 +265,14 @@ import Stripe
"error": "[ERROR]: Unrecognized error while finishing payment: \(String(describing: error))"
]
print("[StripePaymentsPlugin].didFinishWith: \(resultMsg)")
errorCallback(paymentStatusCallback, resultMsg, keepCallback: true)
return
case .userCancellation:
resultMsg = [ "status": "PAYMENT_CANCELED" ]
}
print("[StripePaymentsPlugin].didFinishWith: \(resultMsg)")
successCallback(paymentStatusCallback, resultMsg, keepCallback: true)
}
@ -257,6 +282,8 @@ import Stripe
messageAs: data as [AnyHashable : Any]
)
pluginResult?.setKeepCallbackAs(keepCallback)
print("[StripePaymentsPlugin](successCallback) sending result to \(callbackId), result: \(String(describing: pluginResult))")
self.commandDelegate!.send(pluginResult, callbackId: callbackId)
}
@ -266,6 +293,8 @@ import Stripe
messageAs: data as [AnyHashable : Any]
)
pluginResult?.setKeepCallbackAs(keepCallback)
print("[StripePaymentsPlugin](errorCallback) sending result to \(callbackId), result: \(data)")
self.commandDelegate!.send(pluginResult, callbackId: callbackId)
}

@ -1,5 +1,3 @@
import Alamofire
// TODO:
// We can add an option to execute the charge API-side, in which case
// the developer would also need to provide their 'charge' endpoint,
@ -11,17 +9,8 @@ public class StripePaymentsPluginConfig {
public var ephemeralKeyUrl: String = ""
public var appleMerchantId: String = ""
public var companyName: String = ""
public var requestPaymentImmediately: Bool = true
public var extraHTTPHeaders: HTTPHeaders = [:]
// TODO need xcode for this
func parseExtraHeaders(dict: [String:String]) {
// extraHTTPHeaders.push(new HTTPHeader(dict[something]))
// this actually needs to replace them..dunno. I mean they'll just have
// duplicates and HTTPHeaders should be able to resolve them by updating the header
// if they're already there, using the latest value (later index in array).
// must confirm that works.
}
public var maximumKeyRetries: Int = 0
public var extraHTTPHeaders: [String:String] = [:]
}
let PluginConfig = StripePaymentsPluginConfig()

@ -5,8 +5,9 @@ var StripePaymentsPlugin = function () { };
StripePaymentsPlugin._paymentStatusObserverList = [];
StripePaymentsPlugin._processFunctionList = function (array, param) {
for (var i = 0; i < array.length; i++)
for (var i = 0; i < array.length; i++) {
array[i](param);
}
};
var paymentStatusCallbackProcessor = function (state) {
@ -60,15 +61,16 @@ StripePaymentsPlugin.prototype.requestPayment = function (successCallback, error
//-------------------------------------------------------------------
var instance = new StripePaymentsPlugin();
if (!window.plugins) {
window.plugins = {};
}
if (!window.plugins.StripePaymentsPlugin) {
window.plugins.StripePaymentsPlugin = new StripePaymentsPlugin();
window.plugins.StripePaymentsPlugin = instance;
}
if (typeof module != 'undefined' && module.exports) {
module.exports = StripePaymentsPlugin;
module.exports = instance;
}

Loading…
Cancel
Save