Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RMET-2147 ::: Add Access Token Parameter #13

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion OSPaymentsLib/Error/OSPMTError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum OSPMTError: Int, CustomNSError, LocalizedError {
case stripePaymentMethodCreation = 13
case paymentIssue = 14
case gatewayNotConfigured = 15
case tokenIssue = 19

/// Textual description
public var errorDescription: String? {
Expand Down Expand Up @@ -43,7 +44,9 @@ public enum OSPMTError: Int, CustomNSError, LocalizedError {
case .paymentIssue:
return "Couldn't process payment."
case .gatewayNotConfigured:
return "Couldn't trigger the payment because the requested payment service provider is not configured."
return "Couldn't trigger the payment. The requested payment service provider is not configured yet."
case .tokenIssue:
return "Couldn’t trigger the payment. The access token is not defined."
}
}
}
5 changes: 3 additions & 2 deletions OSPaymentsLib/Gateways/Stripe/OSPMTStripeWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ extension OSPMTStripeWrapper {
/// - Parameters:
/// - payment: Apple Pay's payment request result.
/// - details: Payment details to trigger processing.
/// - accessToken: Authorisation token related with a full payment type.
/// - 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) {
func process(_ payment: PKPayment, with details: OSPMTDetailsModel, and accessToken: String, _ 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)
self.processURLRequest(requestParametersModel, and: accessToken, completion)
case .failure(let error):
completion(.failure(error))
}
Expand Down
5 changes: 3 additions & 2 deletions OSPaymentsLib/OSPMTApplePayHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ extension OSPMTApplePayHandler: OSPMTHandlerDelegate {
/// Sets Payment details and triggers its processing.
/// - Parameters:
/// - detailsModel: payment details information.
/// - accessToken: Authorisation token related with a full payment type.
/// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise.
func set(_ detailsModel: OSPMTDetailsModel, completion: @escaping OSPMTCompletionHandler) {
self.requestBehaviour.trigger(with: detailsModel, completion)
func set(_ detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) {
self.requestBehaviour.trigger(with: detailsModel, and: accessToken, completion)
}
}
10 changes: 6 additions & 4 deletions OSPaymentsLib/OSPMTPayments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ extension OSPMTPayments: OSPMTActionDelegate {
}
}

/// Sets payment details and triggers the request proccess.
/// - Parameter details: Payment details model serialized into a text field.
public func set(_ details: String) {
/// Sets payment details and triggers the request process.
/// - Parameters:
/// - details: Payment details model serialized into a text field.
/// - accessToken: Authorisation token related with a full payment type.
public func set(_ details: String, and accessToken: String?) {
let detailsResult = self.decode(details)
switch detailsResult {
case .success(let detailsModel):
self.handler.set(detailsModel) { [weak self] result in
self.handler.set(detailsModel, and: accessToken) { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let scopeModel):
Expand Down
12 changes: 11 additions & 1 deletion OSPaymentsLib/Protocols/OSPMTActionDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ public protocol OSPMTActionDelegate: AnyObject {
func checkWalletSetup()

/// Sets payment details and triggers the request proccess.
/// - Parameters:
/// - details: Payment details model serialized into a text field.
/// - accessToken: Authorisation token related with a full payment type.
func set(_ details: String, and accessToken: String?)
}

public extension OSPMTActionDelegate {
/// Sets payment details and triggers the request proccess. This uses the default method without the `accessToken` parameter.
/// - Parameter details: Payment details model serialized into a text field.
func set(_ details: String)
func set(_ details: String) {
self.set(details, and: nil)
}
}
8 changes: 6 additions & 2 deletions OSPaymentsLib/Protocols/OSPMTGatewayDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,24 @@ protocol OSPMTGatewayDelegate: AnyObject {
/// - Parameters:
/// - payment: Apple Pay's payment request result.
/// - details: Payment details to trigger processing.
/// - accessToken: Authorisation token related with a full payment type.
/// - 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)
func process(_ payment: PKPayment, with details: OSPMTDetailsModel, and accessToken: String, _ completion: @escaping (Result<OSPMTServiceProviderInfoModel, OSPMTError>) -> Void)
}

extension OSPMTGatewayDelegate {

/// Triggers the backend url request.
/// - Parameters:
/// - requestParameters: Model containing the request body to trigger
/// - accessToken: Authorisation token related with a full payment type.
/// - completion: Payment process result. If returns the process result in case of success or an error otherwise.
func processURLRequest(_ requestParameters: OSPMTRequestParametersModel, _ completion: @escaping (Result<OSPMTServiceProviderInfoModel, OSPMTError>) -> Void) {
func processURLRequest(_ requestParameters: OSPMTRequestParametersModel, and accessToken: String, _ completion: @escaping (Result<OSPMTServiceProviderInfoModel, OSPMTError>) -> Void) {
self.urlRequest.httpMethod = "POST"
self.urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
self.urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")
self.urlRequest.setValue(accessToken, forHTTPHeaderField: "Payments-Token")

self.urlRequest.httpBody = try? JSONEncoder().encode(requestParameters)
let task = self.urlSession.dataTask(with: self.urlRequest) { data, response, error in
guard let response = response as? HTTPURLResponse,
Expand Down
13 changes: 12 additions & 1 deletion OSPaymentsLib/Protocols/OSPMTHandlerDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ protocol OSPMTHandlerDelegate: AnyObject {
/// Sets Payment details and triggers its processing.
/// - Parameters:
/// - detailsModel: payment details information.
/// - accessToken: Authorisation token related with a full payment type.
/// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise.
func set(_ detailsModel: OSPMTDetailsModel, completion: @escaping OSPMTCompletionHandler)
func set(_ detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler)
}

extension OSPMTHandlerDelegate {
/// Sets Payment details and triggers its processing. It uses the default `set` method without the `accessToken` parameter.
/// - Parameters:
/// - detailsModel: payment details information.
/// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise.
func set(_ detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) {
self.set(detailsModel, and: nil, completion)
}
}
37 changes: 28 additions & 9 deletions OSPaymentsLib/Protocols/OSPMTRequestDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,19 @@ protocol OSPMTRequestDelegate: AnyObject {
/// Sets Payment details and triggers its processing.
/// - Parameters:
/// - detailsModel: payment details information.
/// - accessToken: Authorisation token related with a full payment type.
/// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise.
func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler)
func trigger(with detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler)
}

extension OSPMTRequestDelegate {
/// Sets Payment details and triggers its processing. It uses the default method without the `accessToken` parameter.
/// - Parameters:
/// - detailsModel: payment details information.
/// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise.
func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) {
self.trigger(with: detailsModel, and: nil, completion)
}
}

/// Class that implements the `OSPMTRequestDelegate` for Apple Pay, providing it the required that details to work.
Expand All @@ -37,6 +48,7 @@ class OSPMTApplePayRequestBehaviour: NSObject, OSPMTRequestDelegate {
var paymentStatus: PKPaymentAuthorizationStatus = .failure
var paymentScope: OSPMTScopeModel?
var paymentDetails: OSPMTDetailsModel?
var accessToken: String?
var completionHandler: OSPMTCompletionHandler!

/// Constructor method.
Expand All @@ -48,8 +60,14 @@ class OSPMTApplePayRequestBehaviour: NSObject, OSPMTRequestDelegate {
self.requestTriggerType = requestTriggerType
}

func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) {
/// Sets Payment details and triggers its processing.
/// - Parameters:
/// - detailsModel: payment details information.
/// - accessToken: Authorisation token related with a full payment type.
/// - completion: an async closure that can return a successful Payment Scope Model or an error otherwise.
func trigger(with detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) {
self.paymentDetails = detailsModel
self.accessToken = accessToken
self.completionHandler = completion

let result = self.requestTriggerType.createRequestTriggerBehaviour(for: detailsModel, andDelegate: self)
Expand Down Expand Up @@ -125,18 +143,19 @@ extension OSPMTApplePayRequestBehaviour: PKPaymentAuthorizationControllerDelegat
}

if let paymentDetails = paymentDetails, paymentDetails.gateway != nil {
guard let accessToken = self.accessToken, !accessToken.isEmpty else {
return completion(PKPaymentAuthorizationResult(status: self.paymentStatus, errors: [OSPMTError.tokenIssue]))
}

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

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

gatewayWrapper.process(payment, with: paymentDetails) { result in
gatewayWrapper.process(payment, with: paymentDetails, and: accessToken) { result in
var errorArray = [OSPMTError]()
var paymentResultModel: OSPMTServiceProviderInfoModel?

Expand Down
2 changes: 1 addition & 1 deletion OSPaymentsLibTests/OSPMTApplePayHandlerSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class OSPMTMockRequestBehaviour: OSPMTRequestDelegate {
self.scopeModel = scopeModel
}

func trigger(with detailsModel: OSPMTDetailsModel, _ completion: @escaping OSPMTCompletionHandler) {
func trigger(with detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) {
if let error = self.error {
completion(.failure(error))
} else {
Expand Down
2 changes: 1 addition & 1 deletion OSPaymentsLibTests/OSPMTPaymentsSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class OSPMTMockHandler: OSPMTHandlerDelegate {
return self.error
}

func set(_ detailsModel: OSPMTDetailsModel, completion: @escaping OSPMTCompletionHandler) {
func set(_ detailsModel: OSPMTDetailsModel, and accessToken: String?, _ completion: @escaping OSPMTCompletionHandler) {
if let error = self.error {
completion(.failure(error))
} else if let scopeModel = self.scopeModel {
Expand Down
8 changes: 4 additions & 4 deletions OSPaymentsLibTests/OSPMTStripeWrapperSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class OSPMTStripeWrapperSpec: QuickSpec {
it("It should return a Stripe Payment Method Creation error") {
mockAPIDelegate.error = OSPMTError.stripePaymentMethodCreation

stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in
stripeWrapper.process(mockPayment, with: mockDetailsModel, and: OSPMTTestConfigurations.dummyAccessToken) { result in
switch result {
case .failure(let errorResult):
expect(errorResult).to(equal(OSPMTError.stripePaymentMethodCreation))
Expand All @@ -116,7 +116,7 @@ class OSPMTStripeWrapperSpec: QuickSpec {
return (response, OSPMTTestConfigurations.dummyString.data(using: .utf8))
}

stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in
stripeWrapper.process(mockPayment, with: mockDetailsModel, and: OSPMTTestConfigurations.dummyAccessToken) { result in
switch result {
case .failure(let errorResult):
expect(errorResult).to(equal(.paymentIssue))
Expand All @@ -139,7 +139,7 @@ class OSPMTStripeWrapperSpec: QuickSpec {
return (response, resultData)
}

stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in
stripeWrapper.process(mockPayment, with: mockDetailsModel, and: OSPMTTestConfigurations.dummyAccessToken) { result in
switch result {
case .failure(let errorResult):
expect(errorResult).to(equal(.paymentIssue))
Expand All @@ -164,7 +164,7 @@ class OSPMTStripeWrapperSpec: QuickSpec {
return (response, resultData)
}

stripeWrapper.process(mockPayment, with: mockDetailsModel) { result in
stripeWrapper.process(mockPayment, with: mockDetailsModel, and: OSPMTTestConfigurations.dummyAccessToken) { result in
switch result {
case .success(let resultModel):
expect(resultModel).to(equal(OSPMTTestConfigurations.validPaymentProcessResultModel))
Expand Down
2 changes: 2 additions & 0 deletions OSPaymentsLibTests/OSPMTTestConfigurations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,6 @@ struct OSPMTTestConfigurations {

static let invalidPaymentProcessResultModel = OSPMTServiceProviderInfoModel(id: Self.dummyString, status: OSPMTProcessStatus.fail.rawValue)
static let validPaymentProcessResultModel = OSPMTServiceProviderInfoModel(id: Self.dummyString, status: OSPMTProcessStatus.success.rawValue)

static let dummyAccessToken = "dummy"
}
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]

### 2023-01-05
- Feat: Add access token to Full Payment Process (https://outsystemsrd.atlassian.net/browse/RMET-2147).

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

Expand Down
3 changes: 2 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ The method's success is returned through a `OSPMTCallbackDelegate` call. Success
### Set Details and Trigger Payment

```swift
func set(_ details: String)
func set(_ details: String, and: accessToken: String?)
```

Sets payment details and triggers the request proccess. The method contains the following parameter:
- `details`: Payment details model serialized into a text field. This model can be checked in the `OSPMTDetailsModel` structure.
- `accessToken`: Authorisation token related with a full payment type. Can be empty, which should be the case for custom payments.

The method's success is returned through a `OSPMTCallbackDelegate` call. Success operations returns an object of the structure type `OSPMTScopeModel`, encoded in a UTF-8 string. An `OSPMTError` error is returned in case of error.