diff --git a/plugin.xml b/plugin.xml
index 2dbc595..06e4c46 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -54,20 +54,20 @@
-
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
diff --git a/src/ios/AppDelegate.swift b/src/ios/AppDelegate.swift
index c419c29..834e0b3 100644
--- a/src/ios/AppDelegate.swift
+++ b/src/ios/AppDelegate.swift
@@ -1,6 +1,5 @@
import UIKit
-import Stripe
// For Cordova, we can create an AppDelegate extension:
// https://stackoverflow.com/a/29288792
diff --git a/src/ios/PluginConfig.swift b/src/ios/PluginConfig.swift
deleted file mode 100644
index d302ffa..0000000
--- a/src/ios/PluginConfig.swift
+++ /dev/null
@@ -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()
diff --git a/src/ios/APIClient.swift b/src/ios/StripeAPIClient.swift
similarity index 94%
rename from src/ios/APIClient.swift
rename to src/ios/StripeAPIClient.swift
index a2326e0..fef1ba0 100644
--- a/src/ios/APIClient.swift
+++ b/src/ios/StripeAPIClient.swift
@@ -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 = ""
diff --git a/src/ios/PaymentOptions.swift b/src/ios/StripePaymentOptions.swift
similarity index 77%
rename from src/ios/PaymentOptions.swift
rename to src/ios/StripePaymentOptions.swift
index 16d6b6b..7eebb3f 100644
--- a/src/ios/PaymentOptions.swift
+++ b/src/ios/StripePaymentOptions.swift
@@ -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"
}
-}
\ No newline at end of file
+}
diff --git a/src/ios/StripePaymentsPlugin-Bridging-Header.h b/src/ios/StripePaymentsPlugin-Bridging-Header.h
deleted file mode 100644
index b156388..0000000
--- a/src/ios/StripePaymentsPlugin-Bridging-Header.h
+++ /dev/null
@@ -1 +0,0 @@
-#import
diff --git a/src/ios/StripePaymentsPlugin.swift b/src/ios/StripePaymentsPlugin.swift
index 443bfc2..319cfad 100644
--- a/src/ios/StripePaymentsPlugin.swift
+++ b/src/ios/StripePaymentsPlugin.swift
@@ -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
}
}
diff --git a/src/ios/StripePaymentsPluginConfig.swift b/src/ios/StripePaymentsPluginConfig.swift
new file mode 100644
index 0000000..3641b54
--- /dev/null
+++ b/src/ios/StripePaymentsPluginConfig.swift
@@ -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()
diff --git a/www/StripePaymentsPlugin.js b/www/StripePaymentsPlugin.js
index 0b4a57d..c748629 100644
--- a/www/StripePaymentsPlugin.js
+++ b/www/StripePaymentsPlugin.js
@@ -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]);
};
/**