Skip to content

Commit

Permalink
Merge Development Into Main (#10)
Browse files Browse the repository at this point in the history
* chore: Include swiftlint

* feat: Plugin init + Setup Configurations (#1)

Initialise plugin with required structure.
Create structure to deal with Apple Pay. Despite being ready to deal with any kind of dictionary, provide an accelerator to read the configuration from the main bundle.
Add Nimble and Quick through Cocoapods to use BDD for unit testing.

* feat: Check Wallet and Payment Availability (#2)

Add verification for wallet and payment availability. Payment verification is enhanced by also checking it against the configured payment networks and supported capabilities.

* feat: Set Details and Trigger Payment (#3)

Configure the missing payment details and, by mixing it with the configuration info, trigger the payment request.

* refactor: Add DocC documentation and minor fixes. (#4)

Add DocC documentation.
Add empty value check and mandatory fields when fetching configuration properties.

* fix: Payment Setup Verification Failed on Invalid Configuration (#5)

Fix error when verifying payment setup on ReadyToPay method. If some payment network or merchant capabilities are missing, return the associated error.

* fix: Errors and Contact Management (#6)

Clean errors and its codes and messages accordingly.
New OSPMTContact struct that allows the management of the correct shipping and billing information to use on a payment request. This is required due to a limitation on OutSystems related with nullable lists.
Change the OSPMTConfigurationDelegate to OSPMTConfigurationModel, in order to comply with the new OutSystems structure.
Clean code (privatise local methods and make OSPMTPayment's delegate property weak, in order to avoid possible retain cycles).

* fix: Check if GivenName and FamilyName are empty (#7)

* chore: Add Unreleased Section

* Chore: Add Podspec (#9)

* refactor: Simply Generic Method

* chore: Add public podspec

Add public podspec. This implies also updating the readme.md file to something more descriptive and user-friendly.
  • Loading branch information
OS-ricardomoreirasilva committed Nov 16, 2022
1 parent 85bc27b commit e1d22e9
Show file tree
Hide file tree
Showing 16 changed files with 135 additions and 88 deletions.
File renamed without changes.
5 changes: 1 addition & 4 deletions OSPaymentsLib.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

/* Begin PBXBuildFile section */
7507FC1B27FC2AAE003809F6 /* OSPaymentsLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7507FC1227FC2AAE003809F6 /* OSPaymentsLib.framework */; };
7507FC2127FC2AAE003809F6 /* OSPaymentsLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 7507FC1527FC2AAE003809F6 /* OSPaymentsLib.h */; settings = {ATTRIBUTES = (Public, ); }; };
7509DC7728993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7628993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift */; };
7509DC7D28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */; };
7509DC7F28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7509DC7E28996482005BA0D4 /* OSPMTApplePayConfigurationSpec.swift */; };
Expand Down Expand Up @@ -60,7 +59,6 @@
6E048C72FF94991BB4DC4977 /* Pods-OSPaymentsLib.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OSPaymentsLib.debug.xcconfig"; path = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.debug.xcconfig"; sourceTree = "<group>"; };
7063BC573F58EB7154E9975F /* Pods-OSPaymentsLib.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OSPaymentsLib.release.xcconfig"; path = "Target Support Files/Pods-OSPaymentsLib/Pods-OSPaymentsLib.release.xcconfig"; sourceTree = "<group>"; };
7507FC1227FC2AAE003809F6 /* OSPaymentsLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OSPaymentsLib.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7507FC1527FC2AAE003809F6 /* OSPaymentsLib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSPaymentsLib.h; sourceTree = "<group>"; };
7507FC1A27FC2AAE003809F6 /* OSPaymentsLibTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OSPaymentsLibTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7509DC7628993C4C005BA0D4 /* PKMerchantCapability+Adapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PKMerchantCapability+Adapter.swift"; sourceTree = "<group>"; };
7509DC7C28995A07005BA0D4 /* OSPMTAvailabilityDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSPMTAvailabilityDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -158,7 +156,6 @@
7509DC7528993C26005BA0D4 /* Extensions */,
755A8052289BC8EE00426EAA /* Models */,
75EC4D132894142000CF50E2 /* Protocols */,
7507FC1527FC2AAE003809F6 /* OSPaymentsLib.h */,
75EC4D1D289416B600CF50E2 /* OSPMTApplePayHandler.swift */,
75EC4D112893FC3C00CF50E2 /* OSPMTPayments.swift */,
);
Expand Down Expand Up @@ -254,7 +251,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
7507FC2127FC2AAE003809F6 /* OSPaymentsLib.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -398,6 +394,7 @@
};
75895022289989D200670171 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down
6 changes: 4 additions & 2 deletions OSPaymentsLib/Error/OSPMTError.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation

/// All plugin errors that can be thrown
enum OSPMTError: Int, CustomNSError, LocalizedError {
public enum OSPMTError: Int, CustomNSError, LocalizedError {
case invalidConfiguration = 1
case walletNotAvailable = 3
case paymentNotAvailable = 5
Expand All @@ -10,7 +12,7 @@ enum OSPMTError: Int, CustomNSError, LocalizedError {
case paymentCancelled = 11

/// Textual description
var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .invalidConfiguration:
return "Couldn't obtain the payment's informations from the configurations file."
Expand Down
40 changes: 13 additions & 27 deletions OSPaymentsLib/Models/OSPMTConfigurationModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class OSPMTConfigurationModel: Encodable {
}
}

typealias OSPMTConfiguration = [String: Any]
public typealias OSPMTConfiguration = [String: Any]

/// Manages all configuration properties required to enable Apple Pay in the plugin.
class OSPMTApplePayConfiguration: OSPMTConfigurationModel {
Expand All @@ -103,36 +103,22 @@ class OSPMTApplePayConfiguration: OSPMTConfigurationModel {
/// - Parameter source: Source class contaning the configuration.
convenience init(source: OSPMTConfiguration) {
// MARK: Merchant Information
let merchantID = Self.getRequiredProperty(
ofType: String.self, forSource: source, andKey: ConfigurationKeys.merchantID
)
let merchantName = Self.getRequiredProperty(
ofType: String.self, forSource: source, andKey: ConfigurationKeys.merchantName
)
let merchantCountryCode = Self.getRequiredProperty(
ofType: String.self, forSource: source, andKey: ConfigurationKeys.merchantCountryCode
)
let merchantID: String? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.merchantID)
let merchantName: String? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.merchantName)
let merchantCountryCode: String? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.merchantCountryCode)

// MARK: Payment Information
let paymentAllowedNetworks = Self.getRequiredProperty(
ofType: [String].self, forSource: source, andKey: ConfigurationKeys.paymentAllowedNetworks
)
let paymentSupportedCapabilities = Self.getRequiredProperty(
ofType: [String].self, forSource: source, andKey: ConfigurationKeys.paymentSupportedCapabilities
)
let paymentSupportedCardCountries = Self.getProperty(
ofType: [String].self, forSource: source, andKey: ConfigurationKeys.paymentSupportedCardCountries
let paymentAllowedNetworks: [String]? = Self.getRequiredProperty(forSource: source, andKey: ConfigurationKeys.paymentAllowedNetworks)
let paymentSupportedCapabilities: [String]? = Self.getRequiredProperty(
forSource: source, andKey: ConfigurationKeys.paymentSupportedCapabilities
)
let paymentSupportedCardCountries: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.paymentSupportedCardCountries)

// MARK: Shipping Information
let shippingSupportedContacts = Self.getProperty(
ofType: [String].self, forSource: source, andKey: ConfigurationKeys.shippingSupportedContacts
)
let shippingSupportedContacts: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.shippingSupportedContacts)

// MARK: Billing Information
let billingSupportedContacts = Self.getProperty(
ofType: [String].self, forSource: source, andKey: ConfigurationKeys.billingSupportedContacts
)
let billingSupportedContacts: [String]? = Self.getProperty(forSource: source, andKey: ConfigurationKeys.billingSupportedContacts)

self.init(
merchantID: merchantID,
Expand All @@ -154,7 +140,7 @@ private extension OSPMTApplePayConfiguration {
/// - key: Property key to search from.
/// - isRequired: Indicates if the property is mandatory or not.
/// - Returns: The configuration property, if it exists.
static func getProperty<T: Collection>(ofType type: T.Type, forSource source: OSPMTConfiguration, andKey key: String, isRequired: Bool = false) -> T? {
static func getProperty<T: Collection>(forSource source: OSPMTConfiguration, andKey key: String, isRequired: Bool = false) -> T? {
let result = source[key] as? T
return !isRequired || result?.isEmpty == false ? result : nil
}
Expand All @@ -164,8 +150,8 @@ private extension OSPMTApplePayConfiguration {
/// - type: Type of variable to return.
/// - key: Property key to search from.
/// - Returns: The configuration property, if it exists.
static func getRequiredProperty<T: Collection>(ofType type: T.Type, forSource source: OSPMTConfiguration, andKey key: String) -> T? {
self.getProperty(ofType: type, forSource: source, andKey: key, isRequired: true)
static func getRequiredProperty<T: Collection>(forSource source: OSPMTConfiguration, andKey key: String) -> T? {
self.getProperty(forSource: source, andKey: key, isRequired: true)
}
}

Expand Down
2 changes: 2 additions & 0 deletions OSPaymentsLib/OSPMTApplePayHandler.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Foundation

/// Class resopnsible to manage the Apple Pay payment service requests. It delegates every operation type to its manager.
class OSPMTApplePayHandler: NSObject {
let configuration: OSPMTConfigurationModel
Expand Down
12 changes: 7 additions & 5 deletions OSPaymentsLib/OSPMTPayments.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Foundation

/// Class that provides the bridge between the library and 3rd party consumers.
class OSPMTPayments: NSObject {
public class OSPMTPayments: NSObject {
private weak var delegate: OSPMTCallbackDelegate?
private let handler: OSPMTHandlerDelegate

Expand All @@ -16,7 +18,7 @@ class OSPMTPayments: NSObject {
/// - Parameters:
/// - delegate: Handles the asynchronous return calls.
/// - configurationSource: Configuration source, containing all values needed to configure.
convenience init(applePayWithDelegate delegate: OSPMTCallbackDelegate, andConfiguration configurationSource: OSPMTConfiguration = Bundle.main.infoDictionary!) {
public convenience init(applePayWithDelegate delegate: OSPMTCallbackDelegate, andConfiguration configurationSource: OSPMTConfiguration = Bundle.main.infoDictionary!) {
let applePayHandler = OSPMTApplePayHandler(configurationSource: configurationSource)
self.init(delegate: delegate, handler: applePayHandler)
}
Expand All @@ -25,7 +27,7 @@ class OSPMTPayments: NSObject {
// MARK: - Action Methods to be called by Bridge
extension OSPMTPayments: OSPMTActionDelegate {
/// Sets up the payment configuration.
func setupConfiguration() {
public func setupConfiguration() {
let result = self.handler.setupConfiguration()

switch result {
Expand All @@ -37,7 +39,7 @@ extension OSPMTPayments: OSPMTActionDelegate {
}

/// Verifies the device is ready to process a payment, considering the configuration provided before.
func checkWalletSetup() {
public func checkWalletSetup() {
if let error = self.handler.checkWalletAvailability() {
self.delegate?.callback(error: error)
} else {
Expand All @@ -47,7 +49,7 @@ extension OSPMTPayments: OSPMTActionDelegate {

/// Sets payment details and triggers the request proccess.
/// - Parameter details: Payment details model serialized into a text field.
func set(_ details: String) {
public func set(_ details: String) {
let detailsResult = self.decode(details)
switch detailsResult {
case .success(let detailsModel):
Expand Down
12 changes: 0 additions & 12 deletions OSPaymentsLib/OSPaymentsLib.h

This file was deleted.

2 changes: 1 addition & 1 deletion OSPaymentsLib/Protocols/OSPMTActionDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Protocol that provides the server actions the plugin provides.
protocol OSPMTActionDelegate: AnyObject {
public protocol OSPMTActionDelegate: AnyObject {
/// Sets up the payment configuration.
func setupConfiguration()

Expand Down
2 changes: 1 addition & 1 deletion OSPaymentsLib/Protocols/OSPMTCallbackDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Delegate for the callback return calls for the plugin
protocol OSPMTCallbackDelegate: AnyObject {
public protocol OSPMTCallbackDelegate: AnyObject {
func callback(result: String?, error: OSPMTError?)
}

Expand Down
22 changes: 22 additions & 0 deletions OSPaymentsPluginLib.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Pod::Spec.new do |s|
s.name = 'OSPaymentsPluginLib'
s.version = '1.1.0'
s.summary = 'The `OSPaymentsPluginLib-iOS` is a library build using `Swift` that lets you set a payment experience using Apple Pay.'
s.description = <<-DESC
The `OSPaymentsPluginLib-iOS` is a library build using `Swift` that lets you set a payment experience using Apple Pay. It allows to set the payment's details, such as the merchant’s information, payment amount and currency, as well as shipping and billing address. This information can then used to process a payment within an app.
The `OSPMTActionDelegate` protocol, along with the class that implements it - `OSPMTPayments` - allows this interaction, providing the following operations:
- Setup Payment Configuration
- Check if Device is Ready for Payment
- Set Details and Trigger Payment
DESC
s.homepage = 'https://github.com/OutSystems/OSPaymentsLib-iOS'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Mobile Ecosystem Team' => '[email protected]' }
s.source = { :git => 'https://github.com/OutSystems/OSPaymentsLib-iOS.git', :tag => s.version.to_s }

s.ios.deployment_target = '13.0'
s.swift_versions = '5.0'

s.source_files = 'OSPaymentsLib/**/*.swift'
end
11 changes: 7 additions & 4 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### 2022-08-03
## [Unreleased]

### 2022-11-14
- Add `podspec` file.

## 1.0.0

### 2022-08-03
- Feat: Set Payment Details (https://outsystemsrd.atlassian.net/browse/RMET-1723).

### 2022-08-02

- Feat: Check Wallet Availability for Payment (https://outsystemsrd.atlassian.net/browse/RMET-1695).

### 2022-08-01

- Feat: Setup Apple Pay Configurations (https://outsystemsrd.atlassian.net/browse/RMET-1722).

### 2022-04-12

- Create repository.
83 changes: 77 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,81 @@
# OSPaymentsLib
# OSPaymentsPluginLib-iOS

Welcome to **OSPaymentsLib**.
The `OSPaymentsPluginLib-iOS` is a library build using `Swift` that lets you set a payment experience using Apple Pay. It allows to set the payment's details, such as the merchant’s information, payment amount and currency, as well as shipping and billing address. This information can then used to process a payment within an app.

Commands to create the xcframework:
The `OSPMTActionDelegate` protocol, along with the class that implements it - `OSPMTPayments` - allows this interaction, providing the following operations:
- Setup Payment Configuration
- Check if Device is Ready for Payment
- Set Details and Trigger Payment

"sh build.sh" (will create the xcframewotk file in the output folder "build")
Each is detailed on following sections.

Copy and paste the file in the plugin.
path: "PLUGIN_ROOT_FOLDER" src/ios/frameworks/
## Index

- [Motivation](#motivation)
- [Usage](#usage)
- [Methods](#methods)
- [Setup Payment Configuration](#setup-payment-configuration)
- [Check if Device is Ready for Payment](#check-if-device-is-ready-for-payment)
- [Set Details and Trigger Payment](#set-details-and-trigger-payment)

## Motivation

This library is to be used by the [Payments Plugin](https://github.com/OutSystems/cordova-outsystems-payments). The repository contains a `podspec` file that is published and available on the `CocoaPods`' repository, and should be imported on the Cordova bridge as a `pod`.

## Usage

1. Include the `OSPaymentsPluginLib` pod in the Cordova Bridge. o accomplish this, the following needs to be inserted into the `plugin.xml` file. The `spec` field should be changed to the version the developer desires to use.

```xml
<platform>
...
<podspec>
<config>
<source url="https://cdn.cocoapods.org/"/>
</config>
<pods use-frameworks="true">
...
<pod name="OSPaymentsPluginLib" spec="{VERSION TO USE}" />
...
</pods>
</podspec>
...
</platform>
```

2. Go to [Apple Developer Portal](https://developer.apple.com/) and configure the Provisioning Profile with the `Apple Pay Payment Processing` and `In-App Purchase` capabilities enabled.

## Methods

The library provides the following methods to interact with:

### Setup Payment Configuration

```swift
func setupConfiguration()
```

Sets up the payment configuration.

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

### Check if Device is Ready for Payment

```swift
func checkWalletSetup()
```

Verifies the device is ready to process a payment, considering the configuration provided before.

The method's success is returned through a `OSPMTCallbackDelegate` call. Success operations returns an empty string or a `OSPMTError` error otherwise.

### Set Details and Trigger Payment

```swift
func set(_ details: 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.

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.
Binary file removed docs/assets/createRepositoryButton.png
Binary file not shown.
Binary file removed docs/assets/repositoryNameExample.png
Binary file not shown.
Binary file removed docs/assets/useThisTemplateButton.png
Binary file not shown.
26 changes: 0 additions & 26 deletions scripts/build.sh

This file was deleted.

0 comments on commit e1d22e9

Please sign in to comment.