---
# System prepended metadata

title: Northstar Native SDK Client Spec

---

# Northstar Native SDK Client Spec

## BT SDK Card Client


- initized with an API client
- Two top level functions 
```objectivec=
- (void)tokenizeCard:(BTCard *)card 
        completion:(void (^)(BTCardNonce *tokenizedCard, NSError *error))completion
```
- params: card object and completion
- flow: 
    - merchant uses SDK to create a nonce of the input card 
    - merchant passes nonce to their server, which creates and executes the transcation
```objectivec=
- (void)tokenizeCard:(BTCardRequest *)request 
             options:(NSDictionary *)options 
          completion:(void (^)(BTCardNonce * _Nullable, NSError * _Nullable))completionBlock
```
- params: card request and completion
- internally invoked by the other `tokenizeCard` function
    

## Northstar implementation

### Example integration
```kotlin=
// Create a CardClient instance
val cardClient = CardClient(config)

// Create an OrderRequest and Card
val orderRequest = OrderRequest(
    purchaseUnitList = listOf(
        PurchaseUnit(
            amount = Amount(
                currencyCode = CurrencyCode.USD,
                value = "10.00"
            )
        )
    )
)
val card = Card(number = "4032036247327321", expiry = "2024-11")

// Execute order
cardClient.executeOrder(orderRequest, card) { result ->
    when(result) {
        is Success -> {
            // Transaction was executed
        }
        is Failure -> {
            // Error executing transaction
        }
    }
}
```

### 1. Create CardClient


```swift=
CardClient(_ config:) {
    // Use dependency injection to satisfy dependencies 
    // instead of exposing them publicly through the constructor 
    
    // This is something we can add later on iOS if we want to first 
    // getthings working before exploring DI solutions
    self.apiClient = Resolver.resolve()
}
```
The config object passed in here should live in Core and contain all the shared parameters that a merchant would need to give the SDK in order to  perform its operations. Some values that should live in this config:
- ClientID
- Environment
- Access token?
- others?
    
### 2a. Execute transaction passing in an OrderRequest
- To consume card transaction with no card validation and an order request object:
    - https://developer.paypal.com/docs/api/orders/v2/#orders_create
    - Order is created, and immediately executed. The intent is required to be `CAPTURE`, and the status of the order after creation will be `COMPLETED`
- API Doc Reference: https://hackmd.io/oo00FrwyQEe3aT4NI8WcuA?view#Option-1-Create-and-authorizecapture-card-order-immediately
        
```swift=
client.executeOrder(order: OrderRequest, card: Card) { result in
    // POST to /v2/checkout/orders/
    // request body contains: 
    {
        "purchase_units": [ 
            <Purchase_Unit Definition> 
            https://developer.paypal.com/docs/api/orders/v2/#definition-purchase_unit_request
        ],
        "payment_source":{
            "card":{
                "number":"4032036247327321",
                "expiry":"2024-12"
            }
        }
    }

    // response <https://developer.paypal.com/docs/api/orders/v2/#orders-create-response>: 
        - Order Response object
            - Order ID
            - Intent (always CAPTURE)
            - purchase_units
            - status (always COMPLETED)
            - Other response params found here: https://ppaas/api/3719176155270030?tab=apiReference&operation_id=post-_v2_checkout_orders

    // vend result to merchant through completion handler
    switch result {
         case .success(let orderResponse):
             orderResponse.orderID
             orderResponse.intent
             orderResponse.purchaseUnits
             orderResponse.status
             orderResponse. ? 
        case .failure(let error):
            // transaction failed - human readable error information
    }
}
```
    
    
    
### 2b. Execute transaction passing in an OrderID
- Executes a transaction given an order ID and a Card object
- API Doc Reference: https://hackmd.io/oo00FrwyQEe3aT4NI8WcuA?view#Option-3-Create--authorizecapture

```swift=
client.executeOrder(orderID: String, card: Card) { result in
    // POST to either:
        `v2/checkout/orders/<order_id>/authorize` 
        `v2/checkout/orders/<order_id>/capture`
    // request: 
    {
        "payment_source":{
            "card":{
                "number":"4032036247327321",
                "expiry":"2024-12"
            }
        }
    }

    // response: 
        - Order Response object
            - Order ID
            - Intent (always CAPTURE)
            - purchase_units
            - status (always COMPLETED)
            - Other response params found here: https://ppaas/api/3719176155270030?tab=apiReference&operation_id=post-_v2_checkout_orders

    // vend result to the merchant
    switch result {
         case .success(let orderResponse):
             orderResponse.orderID
             orderResponse.intent
             orderResponse.purchaseUnits
             orderResponse.status
             orderResponse. ? 
        case .failure(let error):
            // transaction failed - human readable error information
    }
}
```
    
## Issues and Questions

**Token Source**
- The desire is for a merchant to be able to pass us a token generated from any source (`v1/payments`, `v2/orders`, others?) 
    - per Mark
- EC Tokens generated from the v1 API are not compatible with the v2 order actions: 
    - `v2/checkout/orders/<order_id>/authorize`
    - `v2/checkout/orders/<order_id>/capture`
- In order to satisfy #1 natively, we would need some ability to determine the token source AND properly handle / type the responses from the different potential token sources (ie `INTENT` values are different between `v1` and `v2` APIs)
- **Possible solution:**
        Since this is a problem that will need to be solved by all three platforms (JS, Android, iOS), does it make sense to put this logic and response formatting behind a GraphQL layer that is universally targeted instead of targeting the orders API directly? 
        
**Authorization Intent**
    - Using the v2 API, does an `intent` value of `authorize` make sense for unbranded card transactions? 
    
**Merchant usecase for card validation**
    - Currently, the validation endpoint is marked `INTERNAL`. Is there a reason we would want this exposed? Without this endpoint, there wouldn't be a way for a merchant to do card validation using the orders API
- [/v2/checkout/orders/{OrderID}/validate-payment-method](https://ppaas/api/3719176155270030?tab=apiReference&operation_id=post-_v2_checkout_orders_id_validate_payment_method)
    
    ------

### **Possible implementation of card validation (if it becomes externally available)**
    
- To consume card transaction with card validation: 
    - Post to: [/v2/checkout/orders/{OrderID}/validate-payment-method](https://ppaas/api/3719176155270030?tab=apiReference&operation_id=post-_v2_checkout_orders_id_validate_payment_method)
    - Order can be created client side or server side
    - Documentation: https://hackmd.io/oo00FrwyQEe3aT4NI8WcuA?view#Option-2-Create--validate--approve--authorizecapture

    
    Do we need to provide the ability for the merchant to validate the card data before order execution?
    
```swift
 clientConfig.validate(orderID: orderID, card: Card) { result in
     // validates card data against above API
     response: 
        response object would match the above order object
 }
```
    
    
Create transaction and capture separately
- /v2/checkout/orders/:orderId/validate-payment-method
- Order created, then captured or authorized separately
- Documentation: https://hackmd.io/oo00FrwyQEe3aT4NI8WcuA?view#Option-3-Create--authorizecapture
- **Questions**:
        If a user authorizes a card transaction and wants to capture the same transaction at a future point in time, would the merchant need to pass the card object in again, or would they pass in some part of the authorization response?
        What is the format of the capture / authorization response, and what should be vended to the user?
         