feat(ios): updates after fixing in xcode

pull/2/merge
codinronan 5 years ago
parent 80914bdede
commit abc2950279

@ -54,20 +54,20 @@
</feature>
</config-file>
<framework src="Stripe" type="podspec" spec="~> 15.0.0" />
<framework src="Alamofire" type="podspec" spec="~> 5.0.0-beta.3" />
<!-- <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" /> -->
<!-- https://github.com/cordova-develop/cordova-plugin-pods3/blob/master/plugin.xml -->
<!-- <pods use-frameworks="true">
<pod name="Stripe" spec="" />
<pod name="Alamofire" spec="" />
</pods> -->
<source-file src="src/ios/APIClient.swift" />
<source-file src="src/ios/AppDelegate.swift" />
<source-file src="src/ios/PaymentOptions.swift" />
<source-file src="src/ios/PluginConfig.swift" />
<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>
<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" />
<header-file type="BridgingHeader" src="src/ios/StripePaymentsPlugin-Bridging-Header.h" />
<!-- <framework src="Foundation.framework" /> -->
</platform>

@ -1,6 +1,5 @@
import UIKit
import Stripe
// For Cordova, we can create an AppDelegate extension:
// https://stackoverflow.com/a/29288792

@ -1,22 +0,0 @@
import Alamofire
public class StripePaymentsPluginConfig {
public var publishableKey: String? = nil
public var ephemeralKeyUrl: String? = nil
public var appleMerchantId: String? = nil
public var companyName: String? = nil
public var requestPaymentImmediately: Boolean? = true
public var extraHTTPHeaders: [HTTPHeader]? = []
// 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,
// meaning that the success/fail return value becomes meaningful.
// The extraHTTPHeaders now allows us to do that, to be done later..
// TODO need xcode for this
func parseExtraHeaders(dict: [String:String]) {
// extraHTTPHeaders.push(new HTTPHeader(dict[something]))
}
}
let PluginConfig = StripePaymentsPluginConfig()

@ -1,9 +1,9 @@
import Alamofire
import Stripe
class APIClient: NSObject, STPCustomerEphemeralKeyProvider {
class StripeAPIClient: NSObject, STPCustomerEphemeralKeyProvider {
static let shared = APIClient()
static let shared = StripeAPIClient()
var ephemeralKeyUrl = ""

@ -1,15 +1,15 @@
public struct PaymentOptions {
public struct StripePaymentOptions {
// must be in smallest unit e.g. 1000 for $10.00
public var price: UInt32 = 0
public var price: Int = 0
// 'USD', 'MXN', 'JPY', 'GBP' etc. uppercase.
public var currency: String = "USD"
// 'US', 'PH', the ISO 2-letter code, uppercase.
public var country: String = "US"
init(dict: [String:Any]) {
price = dict["price"] as? UInt32 ?? 0
price = dict["price"] as? Int ?? 0
currency = dict["currency"] as? String ?? "USD"
country = dict["country"] as? String ?? "US"
}
}
}

@ -12,9 +12,9 @@ import Stripe
@objc(StripePaymentsPlugin) class StripePaymentsPlugin: CDVPlugin, STPPaymentContextDelegate {
private var paymentStatusCallback: String? = nil
private let customerContext: STPCustomerContext
private let paymentContext: STPPaymentContext
private var paymentStatusCallback: String = ""
private var customerContext: STPCustomerContext!
private var paymentContext: STPPaymentContext!
override func pluginInitialize() {
super.pluginInitialize()
@ -27,8 +27,8 @@ import Stripe
// MARK: Init Method
@objc(init:)
public func init(command: CDVInvokedUrlCommand) {
@objc(beginStripe:)
public func beginStripe(command: CDVInvokedUrlCommand) {
let error = "The Stripe Publishable Key and ephemeral key generation URL are required"
guard let dict = command.arguments[0] as? [String:Any] ?? nil else {
@ -43,10 +43,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? Boolean ?? true
PluginConfig.requestPaymentImmediately = dict["requestPaymentImmediately"] as? Bool ?? true
if headersDict = dict["extraHTTPHeaders"] as? [String:String] {
PluginConfig.parseExtraHeaders(headersDict)
if let headersDict = dict["extraHTTPHeaders"] as? [String:String] {
PluginConfig.parseExtraHeaders(dict: headersDict)
}
if !self.verifyConfig() {
@ -54,7 +54,7 @@ import Stripe
return
}
APIClient.shared.ephemeralKeyUrl = PluginConfig.ephemeralKeyUrl
StripeAPIClient.shared.ephemeralKeyUrl = PluginConfig.ephemeralKeyUrl
STPPaymentConfiguration.shared().companyName = PluginConfig.companyName
STPPaymentConfiguration.shared().publishableKey = PluginConfig.publishableKey
@ -62,7 +62,7 @@ import Stripe
STPPaymentConfiguration.shared().appleMerchantIdentifier = PluginConfig.appleMerchantId
}
customerContext = STPCustomerContext(keyProvider: APIClient.shared)
customerContext = STPCustomerContext(keyProvider: StripeAPIClient.shared)
paymentContext = STPPaymentContext(customerContext: customerContext)
paymentContext.delegate = self
@ -90,18 +90,24 @@ import Stripe
return
}
let paymentOptions = PaymentOptions(options)
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)
}
// 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
// payment data and clicked 'ok'. That's all.
// After that dialog closes - after paymentContextDidChange is called with
// a selectedPaymentMethod - THEN you want to call requestPayment.
paymentContext.presentPaymentMethodsViewController()
paymentContext.presentPaymentOptionsViewController()
successCallback(command.callbackId, [ "status": "PAYMENT_DIALOG_SHOWN" ])
}
@ -126,57 +132,58 @@ import Stripe
// MARK: STPPaymentContextDelegate
func paymentContext(_ paymentContext: STPPaymentContext, didFailToLoadWithError error: Error) {
let alertController = UIAlertController(
preferredStyle: .alert,
retryHandler: { (action) in
// Retry payment context loading
paymentContext.retryLoading()
}
)
var message = error?.localizedDescription ?? ""
var message = error.localizedDescription
var callbackMessage: String = ""
if let customerKeyError = error as? APIClient.CustomerKeyError {
if let customerKeyError = error as? StripeAPIClient.CustomerKeyError {
switch customerKeyError {
case .ephemeralKeyUrl:
// Fail silently until base url string is set
callbackMessage = "[ERROR]: Please assign a value to `APIClient.shared.ephemeralKeyUrl` before continuing. See `StripePaymentsPlugin.swift`."
callbackMessage = "[ERROR]: Please assign a value to `StripeAPIClient.shared.ephemeralKeyUrl` before continuing. See `StripePaymentsPlugin.swift`."
case .invalidResponse:
// Use customer key specific error message
callbackMessage = "[ERROR]: Missing or malformed response when attempting to call `APIClient.shared.createCustomerKey`. Please check internet connection and backend response."
callbackMessage = "[ERROR]: Missing or malformed response when attempting to call `StripeAPIClient.shared.createCustomerKey`. Please check internet connection and backend response."
message = "Could not retrieve customer information"
}
}
else {
// Use generic error message
callbackMessage = "[ERROR]: Unrecognized error while loading payment context: \(error)"
message = error.localizedDescription ?? "Could not retrieve payment information"
callbackMessage = "[ERROR]: Unrecognized error while loading payment context: \(error.localizedDescription)"
message = "Could not retrieve payment information"
}
print(callbackMessage)
errorCallback(paymentStatusCallback, ["error": callbackMessage], keepCallback: true)
alertController.setMessage(message) // ??
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)
}
func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
var isLoading = paymentContext.isLoading
var isPaymentReady = paymentContext.selectedPaymentMethod != nil
let isLoading = paymentContext.loading
let isPaymentReady = paymentContext.selectedPaymentOption != nil
var label = ""
var image = ""
// https://stackoverflow.com/questions/11592313/how-do-i-save-a-uiimage-to-a-file
if selectedPaymentMethod = paymentContext.selectedPaymentMethod {
label = selectedPaymentMethod.label
if let selectedPaymentOption = paymentContext.selectedPaymentOption {
label = selectedPaymentOption.label
image = ""
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
if let filePath = paths.first?.appendingPathComponent("StripePaymentMethod.jpg") {
// Save image.
do {
try UIImageJPEGRepresentation(selectedPaymentMethod.image, 1)?.write(to: filePath, options: .atomic)
image = filePath
try selectedPaymentOption.image.jpegData(compressionQuality: 1)?.write(to: filePath, options: .atomic)
image = filePath.absoluteString
}
catch { }
}
@ -230,11 +237,9 @@ import Stripe
case .error:
// Use generic error message
print("[ERROR]: Unrecognized error while finishing payment: \(String(describing: error))");
self.viewController.present(UIAlertController(message: "Could not complete payment"), animated: true)
resultMsg = [
"status": "PAYMENT_COMPLETED_ERROR",
error: "[ERROR]: Unrecognized error while finishing payment: \(String(describing: error))"
"error": "[ERROR]: Unrecognized error while finishing payment: \(String(describing: error))"
]
errorCallback(paymentStatusCallback, resultMsg, keepCallback: true)
@ -247,26 +252,25 @@ import Stripe
}
func successCallback(_ callbackId: String, _ data: [String:Any?], keepCallback: Bool = false) {
var pluginResult = CDVPluginResult(
let pluginResult = CDVPluginResult(
status: .ok,
messageAs: data
messageAs: data as [AnyHashable : Any]
)
pluginResult?.setKeepCallbackAs(keepCallback)
self.commandDelegate!.send(pluginResult, callbackId: callbackId)
}
func errorCallback(_ callbackId: String, _ data: [String:Any?], keepCallback: Bool = false) {
var pluginResult = CDVPluginResult(
let pluginResult = CDVPluginResult(
status: .error,
messageAs: data
messageAs: data as [AnyHashable : Any]
)
pluginResult?.setKeepCallbackAs(keepCallback)
self.commandDelegate!.send(pluginResult, callbackId: callbackId)
}
func verifyConfig() -> Bool {
return PluginConfig.publishableKey != nil && !PluginConfig.publishableKey!.isEmpty
&& PluginConfig.ephemeralKeyUrl != nil && !PluginConfig.ephemeralKeyUrl!.isEmpty
return !PluginConfig.publishableKey.isEmpty && !PluginConfig.ephemeralKeyUrl.isEmpty
}
}

@ -0,0 +1,27 @@
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,
// meaning that the success/fail return value becomes meaningful.
// The extraHTTPHeaders now allows us to do that, to be done later..
public class StripePaymentsPluginConfig {
public var publishableKey: String = ""
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.
}
}
let PluginConfig = StripePaymentsPluginConfig()

@ -19,7 +19,7 @@ var paymentStatusCallbackProcessor = function (state) {
* @param {object} config {publishableKey, ephemeralKeyUrl, appleMerchantId, companyName}
*/
StripePaymentsPlugin.prototype.init = function (config, successCallback, errorCallback) {
exec(successCallback, errorCallback, 'StripePaymentsPlugin', 'init', [config]);
exec(successCallback, errorCallback, 'StripePaymentsPlugin', 'beginStripe', [config]);
};
/**

Loading…
Cancel
Save