# Native Payment Buttons
## Requirements
### Eligibility
Need to add support for Venmo, PayPal Credit and Pay Later.
Determine buttons' eligibility with GraphQL query `fundingEligibility`:

Note:
- Preferably make eligibility call when setting `config` to button?
- All of the fields are optional, we need to determine which fields are available for us when me make the call?
- Fields like `currency`, `intent` (and `vault` in the future when we add support for billing agreement/subscription) are important (can change a button's eligibility), but for now they depend on order => need to think about this when we move create order flow to `Checkout.start()` (when the button is clicked)
- Pay Later button will need `buyerCountry`
Questions:
- How are we getting buyer location?
- Ask Mark and see if theres an existing service that mobile can use to get buyer's location
- Use web's pp_geo_loc header stargate
- How do we handle when a buyer/merchant changes currency codes?
### UI
- If a button is not eligible, don't show the button (blank space).
- Is it possible to collapse button height?
- Provide a callback for merchants after eligibility call for them to decide what to do with the blank space for ineligible buttons.
- How do we handle showing buttons when dark mode is enabled?
## Current State (Android)

Android currently has `PaymentButton` which is a custom view that a merchant will add to their layouts. Here are the current customziations.
```xml
<com.paypal.pyplcheckout.merchantIntegration.smartpaymentbutton.PaymentButton
android:id="@+id/paymentButton"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
```
Color:
* gold
* blue
* white
* black
Label:
* PayPal
* Checkout
* Buy Now
* Pay
Button Shape:
* Rounded
* Pill
* Rectangle
Size:
* Small
* Medium
* Large
## Current State (iOS)
### Button config:
type: PaymentButtonType (color + funding type of button):
* paypalGold
* paypalBlue
* paypalWhite
* paypalBlack
* paypalCredit
* venmo
edges: PaymentButtonEdges (shape):
* rounded
* softEdges
* hardEdges
size: PaymentButtonSize (size):
* mini
* collapsed
* expanded
* full
insets (padding)
prefix (text on left side of button image)
suffix (text on right side of button image)
### Button setup
#### PaymentButtonDelegate
```
public protocol PaymentButtonDelegate: AnyObject {
func onButtonStart() // Call when button is tapped
func onButtonFinish(completion: (() -> Void)?) // Call when checkout is finished
}
```
#### Setup
```
/// ViewController
let config = CheckoutConfig()
let button = PaymentButton()
button.setCheckoutConfig(config)
Checkout.start() called on button tap
```
## Future State (iOS)
### Button config
1. Make PaymentButton subclass for each funding source:
```
public enum PaymentButtonColor {
case gold = 0
case white = 1
...
case darkBlue = 4
var color: {
case gold:
return UIColor
case white
}
}
class PaymentButton: UIButton {
}
public class PayPalButton: PaymentButton {
enum Color {
case gold = 0
case white = 1
...
}
}
public class PayPalCreditButton: PaymentButton {
enum Color {
case white = 1
case darkBlue = 4
}
}
```
### Eligibility call
1. Add `currency` to `Config.init()`
2. Call `fundingEligibility` on `Checkout.set(config:)`
```
fundingEligibility(
clientId: clientId,
currency: config.currency,
buyerCountry: Locale.current.regionCode[??? need confirmation]
) {
paypal {
eligible
reasons
}
credit {
eligible
reasons
}
paylater {
eligible
reasons
}
}
// After auth => check if we can get buyerCountry
// First time?
```
### Button setup
#### PaymentButtonDelegate
```
public protocol PaymentButtonDelegate: AnyObject {
func onButtonStart() // Call when button is tapped
func onButtonFinish(completion: (() -> Void)?) // Call when checkout is finished
func onEligibilityStatusChange(status: FundingEligibilityStatus, sender: PaymentButton) // Call when funding eligibility changes. Case: .inProgress, .eligible, .ineligible
}
```
#### Setup
```
/// Start of app lifecycle
let config = CheckoutConfig()
Checkout.set(config: config)
/// ViewController: UIViewController, PaymentButtonDelegate
let button = PaymentButton()
button.delegate = self
```
## Reference
### Elligibility on Web
on the web, there are at least 3 eligibility calls. 2 are used for button rendering and funding eligibility, then 1 more is used for flow eligibility
* “first render” — before the iframe is loaded (because the iframe has paypal.com scoped cookies), we don’t know who the buyer is, but we have the SDK params (intent, currency, vault, clientID, etc.)
* “second render” — when the paypal.com cookies can be read, we know who the buyer is, so we sometimes will fade in a second button like Venmo
* flow eligibility — we don’t have an Order ID until after the button is clicked. at this point, we have all of the information we need to know where to route the user to
On mobile, I could see us having 1 call for now because you don’t have the iframe/cookie issue and aren’t routing users between multiple flows (yet). you’re just sending people to the native pay sheet and that’s it.