Skip to content

Commit

Permalink
fix: Validate PENDING in resume if showSuccessCheckoutOnPendingPaymen…
Browse files Browse the repository at this point in the history
…t flag is true (#957)

* Validate PENDING in resume if flag is true

* Remove unused code

* Added unit tests for CreateResumeService

* Make new flag a bool

* Added strings for fintechture

* Remove redundant enum

* Split out createresume into seperate protocol
  • Loading branch information
NQuinn27 authored Aug 6, 2024
1 parent 25bdd63 commit 88122fa
Show file tree
Hide file tree
Showing 12 changed files with 436 additions and 88 deletions.
12 changes: 12 additions & 0 deletions Sources/PrimerSDK/Classes/Core/Constants/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ extension Strings {
value: "Confirm to pay",
comment: "Confirm button title text")

static let payBySmartTransfer = NSLocalizedString("payBySmartTransfer",
tableName: nil,
bundle: Bundle.primerResources,
value: "Pay by Smart transfer",
comment: "Pay by Smart transfer button title text")

static let payByImmediateTransfer = NSLocalizedString("payByImmediateTransfer",
tableName: nil,
bundle: Bundle.primerResources,
value: "Pay by Immediate transfer",
comment: "Pay by Immediate transfer button title text")

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ private enum CreateResumePaymentCallType: String {

internal class CreateResumePaymentService: CreateResumePaymentServiceProtocol {

let apiClient: PrimerAPIClientProtocol
let apiClient: PrimerAPIClientCreateResumePaymentProtocol

let paymentMethodType: String

init(paymentMethodType: String,
apiClient: PrimerAPIClientProtocol = PrimerAPIClient()) {
apiClient: PrimerAPIClientCreateResumePaymentProtocol = PrimerAPIClient()) {
self.paymentMethodType = paymentMethodType
self.apiClient = apiClient
}
Expand All @@ -45,7 +45,7 @@ internal class CreateResumePaymentService: CreateResumePaymentServiceProtocol {
seal.reject(error)
case .success(let paymentResponse):
do {
try self.validateResponse(paymentResponse: paymentResponse, callType: "create")
try self.validateResponse(paymentResponse: paymentResponse, callType: .create)
seal.fulfill(paymentResponse)
} catch {
seal.reject(error)
Expand All @@ -55,23 +55,10 @@ internal class CreateResumePaymentService: CreateResumePaymentServiceProtocol {
}
}

private func error(forCallType callType: CreateResumePaymentCallType) -> Error {
switch callType {
case .create:
return PrimerError.failedToCreatePayment(paymentMethodType: paymentMethodType,
description: "Failed to create payment",
userInfo: .errorUserInfoDictionary(),
diagnosticsId: UUID().uuidString)
case .resume:
return PrimerError.failedToResumePayment(paymentMethodType: paymentMethodType,
description: "Failed to resume payment",
userInfo: .errorUserInfoDictionary(),
diagnosticsId: UUID().uuidString)
}
}
private func validateResponse(paymentResponse: Response.Body.Payment, callType: CreateResumePaymentCallType) throws {

private func validateResponse(paymentResponse: Response.Body.Payment, callType: String) throws {
if paymentResponse.id == nil || paymentResponse.status == .failed {
if paymentResponse.id == nil || paymentResponse.status == .failed ||
(callType == .resume && paymentResponse.status == .pending && paymentResponse.showSuccessCheckoutOnPendingPayment == false) {
let err = PrimerError.paymentFailed(
paymentMethodType: self.paymentMethodType,
paymentId: paymentResponse.id ?? "unknown",
Expand All @@ -80,7 +67,6 @@ internal class CreateResumePaymentService: CreateResumePaymentServiceProtocol {
diagnosticsId: UUID().uuidString)
ErrorHandler.handle(error: err)
throw err

}
}

Expand All @@ -101,7 +87,7 @@ internal class CreateResumePaymentService: CreateResumePaymentServiceProtocol {
seal.reject(error)
case .success(let paymentResponse):
do {
try self.validateResponse(paymentResponse: paymentResponse, callType: "resume")
try self.validateResponse(paymentResponse: paymentResponse, callType: .resume)
seal.fulfill(paymentResponse)
} catch {
seal.reject(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ extension Response.Body {
public let requiredAction: Response.Body.Payment.RequiredAction?
public let status: Status
public let paymentFailureReason: PrimerPaymentErrorCode.RawValue?
public var showSuccessCheckoutOnPendingPayment: Bool? = false

// swiftlint:disable:next nesting
public enum CodingKeys: String, CodingKey {
case id, paymentId, amount, currencyCode, customer, customerId, order, orderId, requiredAction, status, paymentFailureReason
case id, paymentId, amount, currencyCode, customer, customerId, order, orderId, requiredAction, status, paymentFailureReason, showSuccessCheckoutOnPendingPayment
case dateStr = "date"
}

Expand Down
109 changes: 57 additions & 52 deletions Sources/PrimerSDK/Classes/Data Models/PrimerPaymentMethodType.swift
Original file line number Diff line number Diff line change
@@ -1,58 +1,60 @@
import Foundation

internal enum PrimerPaymentMethodType: String, Codable, CaseIterable, Equatable, Hashable {
case adyenAlipay = "ADYEN_ALIPAY"
case adyenBlik = "ADYEN_BLIK"
case adyenBancontactCard = "ADYEN_BANCONTACT_CARD"
case adyenDotPay = "ADYEN_DOTPAY"
case adyenGiropay = "ADYEN_GIROPAY"
case adyenIDeal = "ADYEN_IDEAL"
case adyenInterac = "ADYEN_INTERAC"
case adyenMobilePay = "ADYEN_MOBILEPAY"
case adyenMBWay = "ADYEN_MBWAY"
case adyenMultibanco = "ADYEN_MULTIBANCO"
case adyenPayTrail = "ADYEN_PAYTRAIL"
case adyenPayshop = "ADYEN_PAYSHOP"
case adyenSofort = "ADYEN_SOFORT"
case adyenTrustly = "ADYEN_TRUSTLY"
case adyenTwint = "ADYEN_TWINT"
case adyenVipps = "ADYEN_VIPPS"
case applePay = "APPLE_PAY"
case atome = "ATOME"
case buckarooBancontact = "BUCKAROO_BANCONTACT"
case buckarooEps = "BUCKAROO_EPS"
case buckarooGiropay = "BUCKAROO_GIROPAY"
case buckarooIdeal = "BUCKAROO_IDEAL"
case buckarooSofort = "BUCKAROO_SOFORT"
case coinbase = "COINBASE"
case goCardless = "GOCARDLESS"
case googlePay = "GOOGLE_PAY"
case hoolah = "HOOLAH"
case iPay88Card = "IPAY88_CARD"
case klarna = "KLARNA"
case mollieBankcontact = "MOLLIE_BANCONTACT"
case mollieIdeal = "MOLLIE_IDEAL"
case opennode = "OPENNODE"
case payNLBancontact = "PAY_NL_BANCONTACT"
case payNLGiropay = "PAY_NL_GIROPAY"
case payNLIdeal = "PAY_NL_IDEAL"
case payNLPayconiq = "PAY_NL_PAYCONIQ"
case paymentCard = "PAYMENT_CARD"
case payPal = "PAYPAL"
case primerTestKlarna = "PRIMER_TEST_KLARNA"
case primerTestPayPal = "PRIMER_TEST_PAYPAL"
case primerTestSofort = "PRIMER_TEST_SOFORT"
case rapydFast = "RAPYD_FAST"
case rapydGCash = "RAPYD_GCASH"
case rapydGrabPay = "RAPYD_GRABPAY"
case rapydPromptPay = "RAPYD_PROMPTPAY"
case rapydPoli = "RAPYD_POLI"
case omisePromptPay = "OMISE_PROMPTPAY"
case twoCtwoP = "TWOC2P"
case xenditOvo = "XENDIT_OVO"
case xenditRetailOutlets = "XENDIT_RETAIL_OUTLETS"
case xfersPayNow = "XFERS_PAYNOW"
case nolPay = "NOL_PAY"
case adyenAlipay = "ADYEN_ALIPAY"
case adyenBlik = "ADYEN_BLIK"
case adyenBancontactCard = "ADYEN_BANCONTACT_CARD"
case adyenDotPay = "ADYEN_DOTPAY"
case adyenGiropay = "ADYEN_GIROPAY"
case adyenIDeal = "ADYEN_IDEAL"
case adyenInterac = "ADYEN_INTERAC"
case adyenMobilePay = "ADYEN_MOBILEPAY"
case adyenMBWay = "ADYEN_MBWAY"
case adyenMultibanco = "ADYEN_MULTIBANCO"
case adyenPayTrail = "ADYEN_PAYTRAIL"
case adyenPayshop = "ADYEN_PAYSHOP"
case adyenSofort = "ADYEN_SOFORT"
case adyenTrustly = "ADYEN_TRUSTLY"
case adyenTwint = "ADYEN_TWINT"
case adyenVipps = "ADYEN_VIPPS"
case applePay = "APPLE_PAY"
case atome = "ATOME"
case buckarooBancontact = "BUCKAROO_BANCONTACT"
case buckarooEps = "BUCKAROO_EPS"
case buckarooGiropay = "BUCKAROO_GIROPAY"
case buckarooIdeal = "BUCKAROO_IDEAL"
case buckarooSofort = "BUCKAROO_SOFORT"
case coinbase = "COINBASE"
case goCardless = "GOCARDLESS"
case googlePay = "GOOGLE_PAY"
case hoolah = "HOOLAH"
case iPay88Card = "IPAY88_CARD"
case klarna = "KLARNA"
case mollieBankcontact = "MOLLIE_BANCONTACT"
case mollieIdeal = "MOLLIE_IDEAL"
case opennode = "OPENNODE"
case payNLBancontact = "PAY_NL_BANCONTACT"
case payNLGiropay = "PAY_NL_GIROPAY"
case payNLIdeal = "PAY_NL_IDEAL"
case payNLPayconiq = "PAY_NL_PAYCONIQ"
case paymentCard = "PAYMENT_CARD"
case payPal = "PAYPAL"
case primerTestKlarna = "PRIMER_TEST_KLARNA"
case primerTestPayPal = "PRIMER_TEST_PAYPAL"
case primerTestSofort = "PRIMER_TEST_SOFORT"
case rapydFast = "RAPYD_FAST"
case rapydGCash = "RAPYD_GCASH"
case rapydGrabPay = "RAPYD_GRABPAY"
case rapydPromptPay = "RAPYD_PROMPTPAY"
case rapydPoli = "RAPYD_POLI"
case omisePromptPay = "OMISE_PROMPTPAY"
case twoCtwoP = "TWOC2P"
case xenditOvo = "XENDIT_OVO"
case xenditRetailOutlets = "XENDIT_RETAIL_OUTLETS"
case xfersPayNow = "XFERS_PAYNOW"
case nolPay = "NOL_PAY"
case fintechtureSmartTransfer = "FINTECTURE_SMART_TRANSFER"
case fintechtureImmediateTransfer = "FINTECHTURE_IMMEDIATE_TRANSFER"

var provider: String {
switch self {
Expand Down Expand Up @@ -130,6 +132,9 @@ internal enum PrimerPaymentMethodType: String, Codable, CaseIterable, Equatable,
return "XFERS"
case .nolPay:
return "NOL_PAY"

case .fintechtureSmartTransfer, .fintechtureImmediateTransfer:
return "FINTECHTURE"
}
}
}
8 changes: 8 additions & 0 deletions Sources/PrimerSDK/Classes/Modules/UserInterfaceModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,8 @@ class UserInterfaceModule: NSObject, UserInterfaceModuleProtocol {
textColor: nil))
case .nolPay:
return nil
case .fintechtureSmartTransfer, .fintechtureImmediateTransfer:
return nil
}
}

Expand Down Expand Up @@ -801,6 +803,12 @@ class UserInterfaceModule: NSObject, UserInterfaceModuleProtocol {
case PrimerPaymentMethodType.twoCtwoP.rawValue:
return Strings.PaymentButton.payInInstallments

case PrimerPaymentMethodType.fintechtureSmartTransfer.rawValue:
return Strings.PaymentButton.payBySmartTransfer

case PrimerPaymentMethodType.fintechtureImmediateTransfer.rawValue:
return Strings.PaymentButton.payByImmediateTransfer

default:
return metadataButtonText
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ protocol PrimerAPIClientProtocol:
PrimerAPIClientBanksProtocol,
PrimerAPIClientPayPalProtocol,
PrimerAPIClientVaultProtocol,
PrimerAPIClientXenditProtocol {
PrimerAPIClientXenditProtocol,
PrimerAPIClientCreateResumePaymentProtocol {

// MARK: Configuration

Expand Down Expand Up @@ -91,19 +92,6 @@ protocol PrimerAPIClientProtocol:
url: URL,
completion: @escaping APICompletion<Bool>)

// MARK: Payments

func createPayment(
clientToken: DecodedJWTToken,
paymentRequestBody: Request.Body.Payment.Create,
completion: @escaping APICompletion<Response.Body.Payment>)

func resumePayment(
clientToken: DecodedJWTToken,
paymentId: String,
paymentResumeRequest: Request.Body.Payment.Resume,
completion: @escaping APICompletion<Response.Body.Payment>)

// MARK: NolPay

func fetchNolSdkSecret(clientToken: DecodedJWTToken,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// PrimerAPIClientCreateResumePaymentProtocol.swift
// PrimerSDK
//
// Created by Niall Quinn on 05/08/24.
//

import Foundation


protocol PrimerAPIClientCreateResumePaymentProtocol {
func createPayment(
clientToken: DecodedJWTToken,
paymentRequestBody: Request.Body.Payment.Create,
completion: @escaping APICompletion<Response.Body.Payment>)

func resumePayment(
clientToken: DecodedJWTToken,
paymentId: String,
paymentResumeRequest: Request.Body.Payment.Resume,
completion: @escaping APICompletion<Response.Body.Payment>)
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 88122fa

Please sign in to comment.