Stripe API API in Swift
Stripe API API in Swift
This guide shows you how to integrate the Stripe API into your Swift application. Full-stack payments platform for cards, bank transfers, wallets, subscriptions, marketplaces, and billing.
Prerequisites
- Swift installed on your system
- An Stripe API API key (sign up at https://stripe.com)
- Basic familiarity with HTTP APIs
Installation
// Use URLSession (built-in) or Swift Package Manager:
// .package(url: "https://github.com/Alamofire/Alamofire", from: "5.0.0")
Basic Usage
import Foundation
let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? "YOUR_API_KEY"
let baseURL = "https://api.stripe.com"
let url = URL(string: "\(baseURL)/v1/resources")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
if let httpResponse = response as? HTTPURLResponse {
print("Status: \(httpResponse.statusCode)")
}
if let data = data, let body = String(data: data, encoding: .utf8) {
print(body)
}
}
task.resume()
RunLoop.main.run(until: Date(timeIntervalSinceNow: 10))
Error Handling
import Foundation
func callAPIWithRetry(url: URL, headers: [String: String]) {
func attemptRequest() {
var request = URLRequest(url: url)
request.httpMethod = "GET"
for (k, v) in headers { request.setValue(v, forHTTPHeaderField: k) }
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error { print("Error: \(error)"); return }
if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 429 {
print("Rate limited. Waiting 60s...")
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(60)) { attemptRequest() }
return
}
print("Status: \(httpResponse.statusCode)")
}
if let data = data, let body = String(data: data, encoding: .utf8) { print(body) }
}.resume()
}
attemptRequest()
RunLoop.main.run(until: Date(timeIntervalSinceNow: 60))
}
let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? "YOUR_API_KEY"
let url = URL(string: "https://api.stripe.com/v1/resources")!
callAPIWithRetry(url: url, headers: ["Authorization": "Bearer \(apiKey)", "Content-Type": "application/json"])
Advanced Usage
import Foundation
class StripeClient {
let apiKey: String
let baseURL: String
let session: URLSession
init(apiKey: String, baseURL: String = "https://api.stripe.com") {
self.apiKey = apiKey
self.baseURL = baseURL.hasSuffix("/") ? String(baseURL.dropLast()) : baseURL
self.session = URLSession.shared
}
func request(method: String, path: String, completion: @escaping (Result<Data, Error>) -> Void) {
let urlString = "\(baseURL)/v1\(path)"
guard let url = URL(string: urlString) else {
completion(.failure(NSError(domain: "InvalidURL", code: 0)))
return
}
var request = URLRequest(url: url)
request.httpMethod = method
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
session.dataTask(with: request) { data, response, error in
if let error = error { completion(.failure(error)); return }
if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode >= 400 {
completion(.failure(NSError(domain: "APIError", code: httpResponse.statusCode))); return
}
completion(.success(data ?? Data()))
}.resume()
}
func listResources(completion: @escaping (Result<Data, Error>) -> Void) {
request(method: "GET", path: "/resources", completion: completion)
}
}
let client = StripeClient(apiKey: ProcessInfo.processInfo.environment["API_KEY"] ?? "YOUR_API_KEY")
client.listResources { result in
switch result {
case .success(let data): print("Got \(data.count) bytes")
case .failure(let error): print("Error: \(error)")
}
}
RunLoop.main.run(until: Date(timeIntervalSinceNow: 10))
Best Practices
- Store your API key in an environment variable, never in source code
- Implement retry logic with exponential backoff for 429 and 5xx errors
- Set reasonable timeouts (10-30 seconds) for all API calls
- Log request IDs from response headers for debugging
- Cache responses where appropriate to reduce API calls