Skip to content

Commit

Permalink
Feat: Add Gateway property to OSPMTDetailsModel (#12)
Browse files Browse the repository at this point in the history
Add `gateway` property to `OSPMTDetailsModel` struct. When authorising payment, confirm that this property corresponds to a configured gateway (on plist).
  • Loading branch information
OS-ricardomoreirasilva committed Dec 13, 2022
1 parent fa63109 commit d96dba9
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 26 deletions.
3 changes: 3 additions & 0 deletions OSPaymentsLib/Error/OSPMTError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum OSPMTError: Int, CustomNSError, LocalizedError {
case gatewaySetFailed = 12
case stripePaymentMethodCreation = 13
case paymentIssue = 14
case gatewayNotConfigured = 15

/// Textual description
public var errorDescription: String? {
Expand Down Expand Up @@ -41,6 +42,8 @@ public enum OSPMTError: Int, CustomNSError, LocalizedError {
return "Couldn't obtain the PaymentMethod from Stripe."
case .paymentIssue:
return "Couldn't process payment."
case .gatewayNotConfigured:
return "Couldn't trigger the payment because the requested payment service provider is not configured."
}
}
}
5 changes: 3 additions & 2 deletions OSPaymentsLib/Gateways/OSPMTGateway.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ 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
static func convert(from text: String?) -> OSPMTGateway? {
guard let text = text, text.lowercased() == "stripe" else { return nil }
return .stripe
}
}
9 changes: 7 additions & 2 deletions OSPaymentsLib/Models/OSPMTDetailsModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct OSPMTDetailsModel: Decodable {
let status: OSPMTStatus
let shippingContact: OSPMTContact
let billingContact: OSPMTContact
let gateway: OSPMTGateway?

/// Keys used to encode and decode the model.
enum CodingKeys: String, CodingKey {
Expand All @@ -55,6 +56,7 @@ struct OSPMTDetailsModel: Decodable {
case status
case shippingContact = "shippingContacts"
case billingContact = "billingContacts"
case gateway = "psp"
}

/// Constructor method.
Expand All @@ -64,12 +66,14 @@ struct OSPMTDetailsModel: Decodable {
/// - status: Final value status.
/// - shippingContact: Shipping properties required for filling.
/// - billingContact: Billiing properties required for filling.
init(amount: Decimal, currency: String, status: OSPMTStatus, shippingContact: OSPMTContact, billingContact: OSPMTContact) {
/// - gateway: Payment service provided to be used for processing, if passed.
init(amount: Decimal, currency: String, status: OSPMTStatus, shippingContact: OSPMTContact, billingContact: OSPMTContact, gateway: String? = nil) {
self.amount = amount
self.currency = currency
self.status = status
self.shippingContact = shippingContact
self.billingContact = billingContact
self.gateway = OSPMTGateway.convert(from: gateway)
}

/// Creates a new instance by decoding from the given decoder.
Expand All @@ -85,8 +89,9 @@ struct OSPMTDetailsModel: Decodable {
let status = try container.decode(OSPMTStatus.self, forKey: .status)
let shippingContact = try container.decode(OSPMTContact.self, forKey: .shippingContact)
let billingContact = try container.decode(OSPMTContact.self, forKey: .billingContact)
let gateway = try container.decodeIfPresent(String.self, forKey: .gateway)
self.init(
amount: amount, currency: currency, status: status, shippingContact: shippingContact, billingContact: billingContact
amount: amount, currency: currency, status: status, shippingContact: shippingContact, billingContact: billingContact, gateway: gateway
)
}
}
Expand Down
44 changes: 22 additions & 22 deletions OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,31 @@ extension OSPMTApplePayRequestBehaviour: PKPaymentAuthorizationControllerDelegat
/// - payment: The authorized payment. This object contains the payment token you need to submit to your payment processor, as well as the billing and shipping information required by the payment request.
/// - completion: The completion handler to call with the result of authorizing the payment.
func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
if let paymentGateway = self.configuration.gatewayModel {
guard let paymentDetails = self.paymentDetails, let gatewayWrapper = OSPMTGatewayFactory.createWrapper(for: paymentGateway)
func setPaymentResults(with errorArray: [OSPMTError], and scopeModel: OSPMTScopeModel?, _ completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
if errorArray.isEmpty, let scopeModel = scopeModel {
self.paymentScope = scopeModel
self.paymentStatus = .success
} else {
self.paymentScope = nil
self.paymentStatus = .failure
}

completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: errorArray))
}

if let paymentDetails = paymentDetails, paymentDetails.gateway != nil {
guard let paymentGateway = self.configuration.gatewayModel, paymentGateway.gatewayEnum == paymentDetails.gateway else {
completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.gatewayNotConfigured]))
return
}

guard let gatewayWrapper = OSPMTGatewayFactory.createWrapper(for: paymentGateway)
else {
completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.gatewaySetFailed]))
return
}

gatewayWrapper.process(payment, with: paymentDetails) { [weak self] result in
guard let self = self else { return }
gatewayWrapper.process(payment, with: paymentDetails) { result in
var errorArray = [OSPMTError]()
var paymentResultModel: OSPMTServiceProviderInfoModel?

Expand All @@ -131,26 +147,10 @@ extension OSPMTApplePayRequestBehaviour: PKPaymentAuthorizationControllerDelegat
errorArray += [error]
}

if errorArray.isEmpty, let scopeModel = payment.createScopeModel(for: paymentResultModel) {
self.paymentScope = scopeModel
self.paymentStatus = .success
} else {
self.paymentScope = nil
self.paymentStatus = .failure
}

completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: errorArray))
setPaymentResults(with: errorArray, and: payment.createScopeModel(for: paymentResultModel), completion)
}
} else {
if let scopeModel = payment.createScopeModel() {
self.paymentScope = scopeModel
self.paymentStatus = .success
} else {
self.paymentScope = nil
self.paymentStatus = .failure
}

completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: []))
setPaymentResults(with: [], and: payment.createScopeModel(), completion)
}
}
}
3 changes: 3 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### 2022-12-12
- Feat: Add Payment Service Provider property to `OSPMTDetailsModel` struct (https://outsystemsrd.atlassian.net/browse/RMET-2095).

### 2022-12-02
- Feat: Add Stripe as Payment Service Provider (https://outsystemsrd.atlassian.net/browse/RMET-2078).

Expand Down

0 comments on commit d96dba9

Please sign in to comment.