-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Stripe as First Payment Gateway (#11)
Add all necessary logic and changes to make payment processing using Stripe including Protocols, Factories and Models to deal with the StripePayments pod. Unit tests are included.
- Loading branch information
1 parent
199b357
commit 8de483c
Showing
600 changed files
with
51,677 additions
and
491 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/// Payment Service Provider enum object | ||
enum OSPMTGateway: String { | ||
case stripe = "Stripe" | ||
} | ||
|
||
extension OSPMTGateway { | ||
|
||
/// Converts a string into a `OSPMTGateway` object. | ||
/// - Parameter text: Text to convert. | ||
/// - Returns: A `OSPMTGateway` enum object if successful. `nil` is returned in case of error. | ||
static func convert(from text: String) -> OSPMTGateway? { | ||
return text.lowercased() == "stripe" ? .stripe : nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import Foundation | ||
|
||
/// Structure responsible for creating a Wrapper for the configured Gateway. | ||
struct OSPMTGatewayFactory { | ||
/// Creates the correct wrapper for the gateway the user has configured. | ||
/// - Parameter configuration: Model with the gateway configuration information. | ||
/// - Returns: The wrapper object is everything is correctly configured. `nil` is returned otherwise. | ||
static func createWrapper(for configuration: OSPMTGatewayModel) -> OSPMTGatewayDelegate? { | ||
guard let gateway = configuration.gatewayEnum, let url = URL(string: configuration.requestURL) else { return nil } | ||
let urlRequest = URLRequest(url: url) | ||
|
||
switch gateway { | ||
case .stripe: | ||
guard let publishableKey = configuration.publishableKey else { return nil } | ||
return OSPMTStripeWrapper(urlRequest: urlRequest, publishableKey: publishableKey) | ||
} | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
OSPaymentsLib/Gateways/Stripe/OSPMTStripeAPIDelegate.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import PassKit | ||
import StripePayments | ||
|
||
/// Delegate class containing the required calls for Stripe's SDK to process. | ||
protocol OSPMTStripeAPIDelegate: AnyObject { | ||
/// Sets the required publishable key, required to trigger payments through Stripe | ||
/// - Parameter publishableKey: Key obtained via Stripe's Dashboard. | ||
func set(_ publishableKey: String) | ||
|
||
/// Retrieves Stripe's Payment Method's Identifier in exchange for Apple Pay's payment request result. | ||
/// - Parameters: | ||
/// - payment: Apple Pay's payment request result. | ||
/// - completion: The exchange operation result. In case of success, it returns the Payment Method Id or an error otherwise. | ||
func getPaymentMethodId(from payment: PKPayment, _ completion: @escaping (Result<String, OSPMTError>) -> Void) | ||
} | ||
|
||
extension STPAPIClient: OSPMTStripeAPIDelegate { | ||
/// Sets the required publishable key, required to trigger payments through Stripe | ||
/// - Parameter publishableKey: Key obtained via Stripe's Dashboard. | ||
func set(_ publishableKey: String) { | ||
self.publishableKey = publishableKey | ||
} | ||
|
||
/// Retrieves Stripe's Payment Method's Identifier in exchange for Apple Pay's payment request result. | ||
/// - Parameters: | ||
/// - payment: Apple Pay's payment request result. | ||
/// - completion: The exchange operation result. In case of success, it returns the Payment Method Id or an error otherwise. | ||
func getPaymentMethodId(from payment: PKPayment, _ completion: @escaping (Result<String, OSPMTError>) -> Void) { | ||
self.createPaymentMethod(with: payment) { paymentMethod, _ in | ||
if let paymentMethod = paymentMethod { | ||
completion(.success(paymentMethod.stripeId)) | ||
} else { | ||
completion(.failure(.stripePaymentMethodCreation)) | ||
} | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
OSPaymentsLib/Gateways/Stripe/OSPMTStripeRequestParametersModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/// Model to manage Stripe's payment process request parameters. This is based on `OSPMTRequestParametersModel`. | ||
final class OSPMTStripeRequestParametersModel: OSPMTRequestParametersModel { | ||
let paymentMethodId: String | ||
let confirm: Bool | ||
|
||
/// Keys used to encode and decode the model. | ||
enum CodingKeys: String, CodingKey { | ||
case paymentMethodId = "payment_method" | ||
case confirm | ||
} | ||
|
||
/// Constructor method. | ||
/// - Parameters: | ||
/// - amount: Amount to charge. | ||
/// - currency: Currency to charge. | ||
/// - paymentMethodId: Stripe object that represents the customer's payment instruments. | ||
/// - confirm: Automatically confirm the triggered payment process. | ||
init(amount: Int, currency: String, paymentMethodId: String, confirm: Bool = true) { | ||
self.paymentMethodId = paymentMethodId | ||
self.confirm = confirm | ||
super.init(amount: amount, currency: currency) | ||
} | ||
|
||
/// Encodes this value into the given encoder. | ||
/// | ||
/// If the value fails to encode anything, `encoder` will encode an empty | ||
/// keyed container in its place. | ||
/// | ||
/// This function throws an error if any values are invalid for the given | ||
/// encoder's format. | ||
/// | ||
/// - Parameter encoder: The encoder to write data to. | ||
override func encode(to encoder: Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
|
||
try container.encode(paymentMethodId, forKey: .paymentMethodId) | ||
try container.encode(confirm, forKey: .confirm) | ||
try super.encode(to: encoder) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import PassKit | ||
import StripeCore | ||
|
||
/// Object responsible for making a Stripe payment process. The Wrapper deals with all calls that are required to Stripe's SDK. | ||
final class OSPMTStripeWrapper: OSPMTGatewayDelegate { | ||
var urlRequest: URLRequest | ||
var urlSession: URLSession | ||
let apiDelegate: OSPMTStripeAPIDelegate | ||
|
||
/// Constructor method. | ||
/// - Parameters: | ||
/// - urlRequest: URL load request object. | ||
/// - urlSession: Coordinator object for network data transfer tasks. | ||
/// - publishableKey: Key required for Stripe's API to trigger calls. | ||
/// - apiDelegate: Object responsible for Stripe's API calls. | ||
init(urlRequest: URLRequest, urlSession: URLSession = .shared, publishableKey: String, apiDelegate: OSPMTStripeAPIDelegate = STPAPIClient.shared) { | ||
self.urlRequest = urlRequest | ||
self.urlSession = urlSession | ||
|
||
apiDelegate.set(publishableKey) | ||
self.apiDelegate = apiDelegate | ||
} | ||
} | ||
|
||
extension OSPMTStripeWrapper { | ||
/// Triggers the process through the configured gateway. | ||
/// - Parameters: | ||
/// - payment: Apple Pay's payment request result. | ||
/// - details: Payment details to trigger processing. | ||
/// - completion: Payment process result. If returns the process result in case of success or an error otherwise. | ||
func process(_ payment: PKPayment, with details: OSPMTDetailsModel, _ completion: @escaping (Result<OSPMTServiceProviderInfoModel, OSPMTError>) -> Void) { | ||
self.apiDelegate.getPaymentMethodId(from: payment) { result in | ||
switch result { | ||
case .success(let paymentMethodId): | ||
let requestParametersModel = OSPMTStripeRequestParametersModel( | ||
amount: details.paymentAmount.multiplying(by: 100).intValue, currency: details.currency, paymentMethodId: paymentMethodId | ||
) | ||
self.processURLRequest(requestParametersModel, completion) | ||
case .failure(let error): | ||
completion(.failure(error)) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.