-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #499 from checkout/release/4.3.0
Merge release/4.3.0 into main
- Loading branch information
Showing
38 changed files
with
1,594 additions
and
276 deletions.
There are no files selected for viewing
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,76 @@ | ||
## Make a payment with a hosted security code | ||
Use our security code component to make a compliant saved card payment in regions where sending a security code is always mandatory. | ||
|
||
Within this flow, we will securely tokenise the security code and return a security code token to your application layer, which you can then use to continue the payment flow with. | ||
|
||
### Step 1: Initialise the configuration | ||
|
||
```swift | ||
var configuration = SecurityCodeComponentConfiguration(apiKey: "PUBLIC_KEY", // set your public key | ||
environment: Frames.Environment.sandbox) // set the environment | ||
``` | ||
|
||
### Step 2: Create a UIView | ||
|
||
Either create a UIView on storyboard (or a nib file) and define the `Custom Class` and `Module` like below and create an `IBOutlet` in the code counterpart: | ||
|
||
<img width="727" alt="Screenshot 2023-11-06 at 11 46 34" src="https://github.com/checkout/frames-ios/assets/125963311/ee19b1f8-f3eb-47ee-a20a-e328bdba7001"> | ||
|
||
Or, create it programmatically: | ||
|
||
```swift | ||
let securityCodeView = SecurityCodeComponent() | ||
securityCodeView.frame = parentView.bounds | ||
parentView.addSubview(securityCodeView) | ||
``` | ||
|
||
### Step 3: Style the component | ||
|
||
We are using a secure display view so it won't be possible to edit the properties of the inner text field. We provide the `SecurityCodeComponentStyle` to allow the component to be configured. Other than text style, all other attributes can be configured like any other `UIView`. | ||
|
||
Note that security code view has a `clear` background by default. | ||
|
||
```swift | ||
let style = SecurityCodeComponentStyle(text: .init(), | ||
font: UIFont.systemFont(ofSize: 24), | ||
textAlignment: .natural, | ||
textColor: .red, | ||
tintColor: .red, | ||
placeholder: "Enter here") | ||
configuration.style = style | ||
``` | ||
|
||
### Step 4: Inject an optional card scheme for granular security code validation | ||
|
||
If you don't define a card scheme, then all 3 and 4 digit security codes are considered valid for all card schemes. If you don't use the SDKs front-end validation, you will get an error at the API level if you don't define a card scheme and the CVV is invalid. If the CVV is length 0, the SDK will throw a validation error when calling `createToken` independent from the injected card scheme. | ||
|
||
```swift | ||
configuration.cardScheme = Card.Scheme(rawValue: "VISA") // or you can directly use `Card.Scheme.visa`. You should be getting the scheme name string values from your backend. | ||
``` | ||
|
||
### Step 5: Call the configure method | ||
|
||
```swift | ||
securityCodeView.configure(with: configuration) { [weak self] isSecurityCodeValid in | ||
DispatchQueue.main.async { | ||
self?.payButton.isEnabled = isSecurityCodeValid | ||
} | ||
} | ||
``` | ||
|
||
### Step 6: Create a security code token | ||
```swift | ||
securityCodeView.createToken { [weak self] result in | ||
DispatchQueue.main.async { | ||
switch result { | ||
case .success(let tokenDetails): | ||
self?.showAlert(with: tokenDetails.token, title: "Success") | ||
|
||
case .failure(let error): | ||
self?.showAlert(with: error.localizedDescription, title: "Failure") | ||
} | ||
} | ||
} | ||
``` | ||
|
||
You can then continue the payment flow with this `token` by passing into a field name as `cvv` in the payment request. |
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
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
33 changes: 33 additions & 0 deletions
33
Checkout/Source/Network/Models/SecurityCode/SecurityCodeError.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,33 @@ | ||
// | ||
// SecurityCodeError.swift | ||
// | ||
// | ||
// Created by Okhan Okbay on 05/10/2023. | ||
// | ||
|
||
import Foundation | ||
|
||
extension TokenisationError { | ||
public enum SecurityCodeError: CheckoutError { | ||
case missingAPIKey | ||
case couldNotBuildURLForRequest | ||
case networkError(NetworkError) | ||
case serverError(TokenisationError.ServerError) | ||
case invalidSecurityCode | ||
|
||
public var code: Int { | ||
switch self { | ||
case .missingAPIKey: | ||
return 4001 | ||
case .couldNotBuildURLForRequest: | ||
return 3007 | ||
case .networkError(let networkError): | ||
return networkError.code | ||
case .serverError(let serverError): | ||
return serverError.code | ||
case .invalidSecurityCode: | ||
return 3006 | ||
} | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
Checkout/Source/Network/Models/SecurityCode/SecurityCodeRequest.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,26 @@ | ||
// | ||
// SecurityCodeRequest.swift | ||
// | ||
// | ||
// Created by Okhan Okbay on 05/10/2023. | ||
// | ||
|
||
import Foundation | ||
|
||
struct SecurityCodeRequest: Encodable, Equatable { | ||
let type: String = "cvv" | ||
let tokenData: TokenData | ||
} | ||
|
||
struct TokenData: Encodable, Equatable { | ||
let securityCode: String | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case securityCode = "cvv" | ||
} | ||
} | ||
|
||
// For logging purposes only | ||
enum SecurityCodeTokenType: String, Codable, Equatable { | ||
case cvv | ||
} |
19 changes: 19 additions & 0 deletions
19
Checkout/Source/Network/Models/SecurityCode/SecurityCodeResponse.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,19 @@ | ||
// | ||
// SecurityCodeResponse.swift | ||
// | ||
// | ||
// Created by Okhan Okbay on 05/10/2023. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct SecurityCodeResponse: Decodable, Equatable { | ||
/// Type of the tokenisation. In SecurityCodeResponse, it's always `cvv` | ||
public let type: String | ||
|
||
/// Reference token | ||
public let token: String | ||
|
||
/// Date/time of the token expiration. The format is `2023-11-01T13:36:16.2003858Z` | ||
public let expiresOn: String | ||
} |
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
Oops, something went wrong.