Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AffirmSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'AffirmSDK'
s.authors = "Affirm, Inc."
s.version = '5.0.38'
s.version = '5.0.39'
s.summary = 'Integrate Affirm into your iOS app'
s.homepage = 'https://github.com/Affirm/affirm-merchant-sdk-ios'
s.license = { :type => "BSD-3-Clause", :file => "LICENSE" }
Expand Down
4 changes: 2 additions & 2 deletions AffirmSDK/AffirmSDK.bundle/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>5.0.38</string>
<string>5.0.39</string>
<key>CFBundleVersion</key>
<string>5.0.38</string>
<string>5.0.39</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions AffirmSDK/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>5.0.38</string>
<string>5.0.39</string>
<key>CFBundleVersion</key>
<string>5.0.38</string>
<string>5.0.39</string>
</dict>
</plist>
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Affirm iOS SDK Changelog
All notable changes to the SDK will be documented in this file.

## Version 5.0.39 (Jan 26, 2026)
- Fix app crash caused by malformed API error JSON response parsing (nil-safety improvements)

## Version 5.0.38 (Oct 14, 2025)
- Bug fixes

Expand Down
153 changes: 153 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Affirm iOS SDK - A merchant SDK that enables iOS apps to integrate Affirm's buy-now-pay-later financing platform. The SDK provides two main components:
1. **Checkout Flow** - Handle purchase financing through Affirm (regular checkout or Virtual Card Network)
2. **Promotional Messaging** - Display "As low as" promotional payment messaging to customers

## Build and Test Commands

### Building the SDK
```bash
# Build the SDK for iOS Simulator
xcodebuild build-for-testing -project AffirmSDK.xcodeproj -scheme AffirmSDK -destination "platform=iOS Simulator,name=iPhone 15"

# Clean build
xcodebuild clean build -project AffirmSDK.xcodeproj -scheme AffirmSDK -destination "platform=iOS Simulator,name=iPhone 15"
```

### Running Tests
```bash
# Run all tests
xcodebuild clean test -project AffirmSDK.xcodeproj -scheme AffirmSDK -destination "platform=iOS Simulator,name=iPhone 15"
```

### Example Apps
```bash
# Install dependencies for example apps
cd Examples
pod install

# Then open Examples.xcworkspace and run the Examples or ExamplesSwift target
```

## Architecture and Code Organization

### Core Source Directory
- **AffirmSDK/** - Main SDK source code (Objective-C .h/.m files)
- **SPM/** - Mirror of AffirmSDK for Swift Package Manager distribution
- **AffirmSDKTests/** - Unit tests
- **Examples/** - Demo apps (Objective-C and Swift)

### Key Components

#### 1. Configuration (`AffirmConfiguration`)
The singleton configuration object that must be initialized at app startup with:
- Public API key
- Environment (sandbox vs production)
- Locale and country code
- Currency
- Merchant name

#### 2. Checkout Flow (`AffirmCheckout` + `AffirmCheckoutViewController`)
**AffirmCheckout**: The data model containing:
- Items being purchased
- Shipping/billing details
- Tax and shipping amounts
- Discounts and metadata
- Total amount (amounts are in dollars, not cents)

**AffirmCheckoutViewController**: Handles the checkout UI flow with two modes:
- **Regular Checkout**: Returns a checkout token via `checkout:completedWithToken:`
- **VCN (Virtual Card Network)**: Returns credit card info via `vcnCheckout:completedWithCreditCard:`

Key parameters:
- `useVCN`: Boolean to toggle between regular and VCN checkout
- `getReasonCodes`: Boolean to get cancellation reason codes
- `cardAuthWindow`: Authorization window for VCN (in minutes)

#### 3. Promotional Messaging (`AffirmPromotionalButton`)
Displays "As low as $X/month" messaging inline in the app. Configuration options:
- HTML styling (with remote fonts/CSS)
- Local font styling
- Raw HTML string rendering
- Automatically hides if no promo is available

Tapping the button opens `AffirmPrequalModalViewController` for prequalification.

#### 4. Data Fetching (`AffirmDataHandler`)
Provides raw promotional message strings and handles network requests for promo data.

#### 5. Network Layer (`AffirmRequest`, `AffirmClient`)
Request/response objects for:
- **AffirmPromoRequest/Response**: Fetching promotional messages
- **AffirmCheckoutRequest/Response**: Creating checkout sessions
- **AffirmLogRequest**: Event tracking
- **AffirmErrorResponse**: Error handling

### Important Data Models
- **AffirmItem**: Individual purchase items with SKU, price, quantity
- **AffirmShippingDetail**: Shipping address information
- **AffirmBillingDetail**: Billing address information
- **AffirmDiscount**: Discount information
- **AffirmCreditCard**: VCN card details returned from checkout
- **AffirmReasonCode**: Cancellation reason codes
- **AffirmOrder/AffirmProduct**: Order tracking models

### Distribution Methods

The SDK supports multiple distribution methods, with source duplicated across:
1. **CocoaPods**: Uses `AffirmSDK/` directory
2. **Carthage**: Uses `AffirmSDK/` directory
3. **Swift Package Manager**: Uses `SPM/` directory (includes XIBs and bundle resources)
4. **Manual Integration**: Direct drag-and-drop of `AffirmSDK/` folder

**IMPORTANT**: When making code changes, update BOTH `AffirmSDK/` and `SPM/` directories to maintain consistency across distribution methods.

## Key Implementation Notes

### Amount Handling
- All monetary amounts should be in **dollars** (not cents)
- Round to nearest dollar before passing to SDK methods
- SDK converts to cents internally for API calls

### Checkout Token Flow
1. User completes checkout → SDK returns token
2. Token must be sent to merchant server
3. Merchant server uses token to authorize charge via Affirm API

### VCN Checkout Flow
1. User completes VCN checkout → SDK returns `AffirmCreditCard` object
2. Merchant processes card through existing payment gateway
3. No server-side Affirm API call needed

### Web View Architecture
- All user-facing flows use `WKWebView` via `AffirmBaseWebViewController`
- Shared `WKProcessPool` in `AffirmConfiguration` for cookie/session persistence
- JavaScript bridge for communication between native and web layers

### Environment Configuration
Two environments available:
- `AffirmEnvironmentSandbox`: For testing
- `AffirmEnvironmentProduction`: For live transactions

Get URLs via `AffirmConfiguration` methods:
- `jsURL`: Affirm JavaScript URL
- `promosURL`: Promotional messaging endpoint
- `checkoutURL`: Checkout endpoint
- `trackerURL`: Analytics endpoint

## Testing Notes

Test targets:
- **AffirmSDK** (main scheme): Framework target
- **AffirmSDKTests**: Unit test suite covering checkout, configuration, and promo functionality

Tests focus on:
- Model serialization/deserialization
- Configuration validation
- Checkout object creation
- Promotional message formatting
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ github "Affirm/affirm-merchant-sdk-ios"
From Xcode 11+ :

1. Select File > Swift Packages > Add Package Dependency. Enter `https://github.com/Affirm/affirm-merchant-sdk-ios` in the "Choose Package Repository" dialog.
2. In the next page, specify the version resolving rule as "Up to Next Major" with "5.0.38".
2. In the next page, specify the version resolving rule as "Up to Next Major" with "5.0.39".
3. After Xcode checked out the source and resolving the version, you can choose the "AffirmSDK" library and add it to your app target.

For more info, read [Adding Package Dependencies to Your App](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) from Apple.
Expand All @@ -38,7 +38,7 @@ Alternatively, you can also add AffirmSDK to your `Package.swift` file:

```swift
dependencies: [
.package(url: "https://github.com/Affirm/affirm-merchant-sdk-ios", .upToNextMajor(from: "5.0.38"))
.package(url: "https://github.com/Affirm/affirm-merchant-sdk-ios", .upToNextMajor(from: "5.0.39"))
]
```

Expand Down
6 changes: 3 additions & 3 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ How to upgrade?
If you want to upgrade you sdk to the lastest, please check the following points:

## Version
The latest version is `v5.0.38`, you can upgrade sdk by [CocoaPods](https://cocoapods.org/) and [Carthage](https://github.com/Carthage/Carthage).
The latest version is `v5.0.39`, you can upgrade sdk by [CocoaPods](https://cocoapods.org/) and [Carthage](https://github.com/Carthage/Carthage).

For example:

if you use [CocoaPods](https://cocoapods.org/), please make sure you pod repo contains `v5.0.38`, you can use `pod search AffirmSDK` to check it. Otherwise, you should update pod repo before upgrade.
if you use [CocoaPods](https://cocoapods.org/), please make sure you pod repo contains `v5.0.39`, you can use `pod search AffirmSDK` to check it. Otherwise, you should update pod repo before upgrade.


## Fetch updated library

If you already use specific sdk version in Podfile, please modify the line related to affirmSDK as follows:

```
pod 'AffirmSDK', '~> 5.0.38'
pod 'AffirmSDK', '~> 5.0.39'
```

Otherwise, just use `pod update AffirmSDK` in terminal to update AffirmSDK.
Expand Down
Loading