From 9a04341222a79329752a5ac8ff86e3155f3649d7 Mon Sep 17 00:00:00 2001 From: Andrew Edwards Date: Sun, 3 Nov 2019 18:40:09 -0500 Subject: [PATCH 1/3] Added accountLinks API and updated changes to 2019-10-08 API. --- README.md | 1 + Sources/StripeKit/API/Helpers/Endpoints.swift | 4 ++ .../API/Routes/AccountLinkRoutes.swift | 53 +++++++++++++++++++ .../StripeKit/API/Routes/AccountRoutes.swift | 3 +- Sources/StripeKit/API/StripeClient.swift | 3 ++ Sources/StripeKit/API/StripeRequest.swift | 2 +- .../Connect/Account Links/AccountLink.swift | 30 +++++++++++ .../Models/Connect/Accounts/Account.swift | 6 ++- .../Models/Connect/Persons/Person.swift | 12 +++-- 9 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 Sources/StripeKit/API/Routes/AccountLinkRoutes.swift create mode 100644 Sources/StripeKit/Models/Connect/Account Links/AccountLink.swift diff --git a/README.md b/README.md index 700e0085..36c20cc8 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ None of the API calls throw errors. Instead each route returns a successful `Eve --- ### Connect * [x] Account +* [x] Account Links * [x] Application Fee Refunds * [x] Application Fees * [x] Country Specs diff --git a/Sources/StripeKit/API/Helpers/Endpoints.swift b/Sources/StripeKit/API/Helpers/Endpoints.swift index c8defe99..e66d47d2 100644 --- a/Sources/StripeKit/API/Helpers/Endpoints.swift +++ b/Sources/StripeKit/API/Helpers/Endpoints.swift @@ -222,6 +222,8 @@ internal enum StripeAPIEndpoint { case scheduledQueryRun case scheduledQueryRuns(String) + case accountLinks + var endpoint: String { switch self { case .balance: return APIBase + APIVersion + "balance" @@ -407,6 +409,8 @@ internal enum StripeAPIEndpoint { case .scheduledQueryRun: return APIBase + APIVersion + "sigma/scheduled_query_runs" case .scheduledQueryRuns(let query): return APIBase + APIVersion + "sigma/scheduled_query_runs/\(query)" + + case .accountLinks: return APIBase + APIVersion + "account_links" } } } diff --git a/Sources/StripeKit/API/Routes/AccountLinkRoutes.swift b/Sources/StripeKit/API/Routes/AccountLinkRoutes.swift new file mode 100644 index 00000000..338aa8ae --- /dev/null +++ b/Sources/StripeKit/API/Routes/AccountLinkRoutes.swift @@ -0,0 +1,53 @@ +// +// AccountLinkRoutes.swift +// +// +// Created by Andrew Edwards on 11/3/19. +// + +import NIO +import NIOHTTP1 +import Foundation + +public protocol AccountLinkRoutes { + + /// Creates an AccountLink object that returns a single-use Stripe URL that the user can redirect their user to in order to take them through the Connect Onboarding flow. + /// - Parameter account: The identifier of the account to create an account link for. + /// - Parameter failureUrl: The URL that the user will be redirected to if the account link is no longer valid. + /// - Parameter successUrl: The URL that the user will be redirected to upon leaving or completing the linked flow successfully. + /// - Parameter type: The type of account link the user is requesting. Possible values are `custom_account_verification` or `custom_account_update`. + /// - Parameter collect: The information the platform wants to collect from users up-front. Possible values are `currently_due` and `eventually_due`. + func create(account: String, + failureUrl: String, + successUrl: String, + type: AccountLinkCreationType, + collect: AccountLinkCreationCollectType?) -> EventLoopFuture + + var headers: HTTPHeaders { get set } +} + +public struct StripeAccountLinkRoutes: AccountLinkRoutes { + private let apiHandler: StripeAPIHandler + public var headers: HTTPHeaders = [:] + + init(apiHandler: StripeAPIHandler) { + self.apiHandler = apiHandler + } + + public func create(account: String, + failureUrl: String, + successUrl: String, + type: AccountLinkCreationType, + collect: AccountLinkCreationCollectType?) -> EventLoopFuture { + var body: [String: Any] = ["account": account, + "failure_url": failureUrl, + "success_url": successUrl, + "type": type.rawValue] + + if let collect = collect { + body["collect"] = collect.rawValue + } + + return apiHandler.send(method: .POST, path: StripeAPIEndpoint.accountLinks.endpoint, body: .string(body.queryParameters), headers: headers) + } +} diff --git a/Sources/StripeKit/API/Routes/AccountRoutes.swift b/Sources/StripeKit/API/Routes/AccountRoutes.swift index ad35fae9..526767a9 100644 --- a/Sources/StripeKit/API/Routes/AccountRoutes.swift +++ b/Sources/StripeKit/API/Routes/AccountRoutes.swift @@ -23,8 +23,7 @@ public protocol AccountRoutes { /// - businessType: The business type. Can be `individual` or `company`. /// - company: Information about the company or business. This field is null unless `business_type` is set to `company`. /// - defaultCurrency: Three-letter ISO currency code representing the default currency for the account. This must be a currency that Stripe supports in the account’s country. - /// - externalAccount: A card or bank account to attach to the account. You can provide either a token, like the ones returned by Stripe.js, or a dictionary, as documented in the `external_account` parameter for [bank account](https://stripe.com/docs/api#account_create_bank_account) creation. - /// By default, providing an external account sets it as the new default external account for its currency, and deletes the old default if one exists. To add additional external accounts without replacing the existing default for the currency, use the bank account or card creation API. + /// - externalAccount: A card or bank account to attach to the account. You can provide either a token, like the ones returned by Stripe.js, or a dictionary, as documented in the `external_account` parameter for [bank account](https://stripe.com/docs/api#account_create_bank_account) creation. By default, providing an external account sets it as the new default external account for its currency, and deletes the old default if one exists. To add additional external accounts without replacing the existing default for the currency, use the bank account or card creation API. /// - individual: Information about the person represented by the account. This field is null unless `business_type` is set to `individual`. /// - metadata: A set of key-value pairs that you can attach to an `Account` object. This can be useful for storing additional information about the account in a structured format. /// - requestedCapabilities: The set of capabilities you want to unlock for this account (US only). Each capability will be inactive until you have provided its specific requirements and Stripe has verified them. An account may have some of its requested capabilities be active and some be inactive. This will be unset if you POST an empty value. diff --git a/Sources/StripeKit/API/StripeClient.swift b/Sources/StripeKit/API/StripeClient.swift index 2bbfb638..509cd763 100644 --- a/Sources/StripeKit/API/StripeClient.swift +++ b/Sources/StripeKit/API/StripeClient.swift @@ -60,6 +60,8 @@ public final class StripeClient { public var locations: LocationRoutes public var readers: ReaderRoutes public var scheduledQueryRuns: ScheduledQueryRunRoutes + public var accountLinks: AccountLinkRoutes + private let client: HTTPClient public init(eventLoop: EventLoopGroup, apiKey: String) { @@ -117,6 +119,7 @@ public final class StripeClient { locations = StripeLocationRoutes(apiHandler: handler) readers = StripeReaderRoutes(apiHandler: handler) scheduledQueryRuns = StripeScheduledQueryRunRoutes(apiHandler: handler) + accountLinks = StripeAccountLinkRoutes(apiHandler: handler) } deinit { diff --git a/Sources/StripeKit/API/StripeRequest.swift b/Sources/StripeKit/API/StripeRequest.swift index 5fc59ace..2539e2ef 100644 --- a/Sources/StripeKit/API/StripeRequest.swift +++ b/Sources/StripeKit/API/StripeRequest.swift @@ -52,7 +52,7 @@ public struct StripeDefaultAPIHandler: StripeAPIHandler { body: HTTPClient.Body = .string(""), headers: HTTPHeaders = [:]) -> EventLoopFuture { - var _headers: HTTPHeaders = ["Stripe-Version": "2019-05-16", + var _headers: HTTPHeaders = ["Stripe-Version": "2019-10-08", "Authorization": "Bearer \(apiKey)", "Content-Type": "application/x-www-form-urlencoded"] headers.forEach { _headers.replaceOrAdd(name: $0.name, value: $0.value) } diff --git a/Sources/StripeKit/Models/Connect/Account Links/AccountLink.swift b/Sources/StripeKit/Models/Connect/Account Links/AccountLink.swift new file mode 100644 index 00000000..3348fb5f --- /dev/null +++ b/Sources/StripeKit/Models/Connect/Account Links/AccountLink.swift @@ -0,0 +1,30 @@ +// +// AccountLink.swift +// +// +// Created by Andrew Edwards on 11/3/19. +// + +import Foundation + +/// The [Account Link Object](https://stripe.com/docs/api/account_links/object). +public struct AccountLink: StripeModel { + /// String representing the object’s type. Objects of the same type share the same value. + public var object: String + /// Time at which the object was created. Measured in seconds since the Unix epoch. + public var created: Date? + /// The timestamp at which this account link will expire. + public var expiresAt: Date? + /// The URL for the account link. + public var url: String? +} + +public enum AccountLinkCreationType: String, StripeModel { + case customAccountVerification = "custom_account_verification" + case customAccountUpdate = "custom_account_update" +} + +public enum AccountLinkCreationCollectType: String, StripeModel { + case currentlyDue = "currently_due" + case eventuallyDue = "eventually_due" +} diff --git a/Sources/StripeKit/Models/Connect/Accounts/Account.swift b/Sources/StripeKit/Models/Connect/Accounts/Account.swift index 83618bf7..63412b0e 100644 --- a/Sources/StripeKit/Models/Connect/Accounts/Account.swift +++ b/Sources/StripeKit/Models/Connect/Accounts/Account.swift @@ -84,12 +84,14 @@ public enum StripeConnectAccountBusinessType: String, StripeModel { } public struct StripeConnectAccountCapablities: StripeModel { + /// The status of the card issuing capability of the account, or whether you can use Issuing to distribute funds on cards + public var cardIssuing: StripeConnectAccountCapabilitiesStatus? /// The status of the card payments capability of the account, or whether the account can directly process credit and debit card charges. public var cardPayments: StripeConnectAccountCapabilitiesStatus? /// The status of the legacy payments capability of the account. public var legacyPayments: StripeConnectAccountCapabilitiesStatus? - /// The status of the platform payments capability of the account, or whether your platform can process charges on behalf of the account. - public var platformPayments: StripeConnectAccountCapabilitiesStatus? + /// The status of the transfers capability of the account, or whether your platform can transfer funds to the account. + public var transfers: StripeConnectAccountCapabilitiesStatus? } public enum StripeConnectAccountCapabilitiesStatus: String, StripeModel { diff --git a/Sources/StripeKit/Models/Connect/Persons/Person.swift b/Sources/StripeKit/Models/Connect/Persons/Person.swift index a2db33d5..87aa26b3 100644 --- a/Sources/StripeKit/Models/Connect/Persons/Person.swift +++ b/Sources/StripeKit/Models/Connect/Persons/Person.swift @@ -62,14 +62,14 @@ public enum StripePersonGender: String, StripeModel { } public struct StripePersonRelationship: StripeModel { - public var accountOpener: Bool? + public var representative: Bool? public var director: Bool? public var owner: Bool? public var percentOwnership: Decimal? public var title: String? private enum CodingKeys: String, CodingKey { - case accountOpener = "account_opener" + case representative case director case owner case percentOwnership = "percent_ownership" @@ -90,6 +90,7 @@ public struct StripePersonRequirements: StripeModel { } public struct StripePersonVerification: StripeModel { + public var additionalDocument: StripePersonVerificationDocument? public var details: String? public var detailsCode: StripePersonVerificationDetailsCode? public var document: StripePersonVerificationDocument? @@ -104,7 +105,12 @@ public struct StripePersonVerification: StripeModel { } public enum StripePersonVerificationDetailsCode: String, StripeModel { - case scanNameMismatch = "scan_name_mismatch" + case documentAddressMismatch = "document_address_mismatch" + case documentDobMismatch = "document_dob_mismatch" + case documentDuplicateType = "document_duplicate_type" + case documentIdNumberMismatch = "document_id_number_mismatch" + case documentNameMismatch = "document_name_mismatch" + case documentNationalityMismatch = "document_nationality_mismatch" case failedKeyedIdentity = "failed_keyed_identity" case failedOther = "failed_other" } From 4b9cbc889f26f66805c3a7c5a3079c94acaa2bb6 Mon Sep 17 00:00:00 2001 From: Andrew Edwards Date: Tue, 5 Nov 2019 21:37:25 -0500 Subject: [PATCH 2/3] Updated API to 2019-11-05 --- .../StripeKit/API/Routes/CustomerRoutes.swift | 170 +++++++++++++----- .../API/Routes/SubscriptionRoutes.swift | 89 +++++++-- Sources/StripeKit/API/StripeRequest.swift | 2 +- .../Billing/Subscriptions/Subscription.swift | 29 ++- .../Core Resources/Customers/Customer.swift | 40 ++--- 5 files changed, 242 insertions(+), 88 deletions(-) diff --git a/Sources/StripeKit/API/Routes/CustomerRoutes.swift b/Sources/StripeKit/API/Routes/CustomerRoutes.swift index 994f98dd..cb4f6e76 100644 --- a/Sources/StripeKit/API/Routes/CustomerRoutes.swift +++ b/Sources/StripeKit/API/Routes/CustomerRoutes.swift @@ -13,29 +13,39 @@ public protocol CustomerRoutes { /// Creates a new customer object. /// /// - Parameters: - /// - accountBalance: An integer amount that represents the account balance for your customer. Account balances only affect invoices. A negative amount represents a credit that decreases the amount due on an invoice; a positive amount increases the amount due on an invoice. + /// - address: The customer’s address. + /// - balance: An integer amount that represents the account balance for your customer. Account balances only affect invoices. A negative amount represents a credit that decreases the amount due on an invoice; a positive amount increases the amount due on an invoice. /// - coupon: The code of the coupon to apply to this subscription. A coupon applied to a subscription will only affect invoices created for that particular subscription. This will be unset if you POST an empty value. /// - description: An arbitrary string that you can attach to a customer object. It is displayed alongside the customer in the dashboard. This will be unset if you POST an empty value. /// - email: Customer’s email address. It’s displayed alongside the customer in your dashboard and can be useful for searching and tracking. This may be up to 512 characters. This will be unset if you POST an empty value. /// - invoicePrefix: The prefix for the customer used to generate unique invoice numbers. Must be 3–12 uppercase letters or numbers. /// - invoiceSettings: Default invoice settings for this customer. /// - metadata: A set of key-value pairs that you can attach to a customer object. It can be useful for storing additional information about the customer in a structured format. + /// - name: The customer’s full name or business name. /// - paymentMethod: ID of the PaymentMethod to attach to the customer + /// - phone: The customer’s phone number. + /// - preferredLocales: Customer’s preferred languages, ordered by preference. /// - shipping: The customer’s shipping information. Appears on invoices emailed to this customer. /// - source: The source can be a Token or a Source, as returned by Elements. You must provide a source if the customer does not already have a valid source attached, and you are subscribing the customer to be charged automatically for a plan that is not free. \n Passing source will create a new source object, make it the customer default source, and delete the old customer default if one exists. If you want to add an additional source, instead use the card creation API to add the card and then the customer update API to set it as the default. \n Whenever you attach a card to a customer, Stripe will automatically validate the card. - /// - taxInfo: The customer’s tax information. Appears on invoices emailed to this customer. + /// - taxExempt: The customer’s tax exemption. One of none, exempt, or reverse. + /// - taxIdData: The customer’s tax IDs. /// - Returns: A `StripeCustomer`. - func create(accountBalance: Int?, + func create(address: [String: Any]?, + balance: Int?, coupon: String?, description: String?, email: String?, invoicePrefix: String?, invoiceSettings: [String: Any]?, metadata: [String: String]?, + name: String?, paymentMethod: String?, + phone: String?, + preferredLocales: [String]?, shipping: [String: Any]?, source: Any?, - taxInfo: [String: String]?) -> EventLoopFuture + taxExempt: StripeCustomerTaxExempt?, + taxIdData: [[String: Any]]?) -> EventLoopFuture /// Retrieves the details of an existing customer. You need only supply the unique customer identifier that was returned upon customer creation. @@ -48,7 +58,8 @@ public protocol CustomerRoutes { /// /// - Parameters: /// - customer: The identifier of the customer to be updated. - /// - accountBalance: An integer amount that represents the account balance for your customer. Account balances only affect invoices. A negative amount represents a credit that decreases the amount due on an invoice; a positive amount increases the amount due on an invoice. + /// - address: The customer’s address. + /// - balance: An integer amount that represents the account balance for your customer. Account balances only affect invoices. A negative amount represents a credit that decreases the amount due on an invoice; a positive amount increases the amount due on an invoice. /// - coupon: The code of the coupon to apply to this subscription. A coupon applied to a subscription will only affect invoices created for that particular subscription. This will be unset if you POST an empty value. /// - defaultSource: ID of the default payment source for the customer. /// - description: An arbitrary string that you can attach to a customer object. It is displayed alongside the customer in the dashboard. This will be unset if you POST an empty value. @@ -56,12 +67,15 @@ public protocol CustomerRoutes { /// - invoicePrefix: The prefix for the customer used to generate unique invoice numbers. Must be 3–12 uppercase letters or numbers. /// - invoiceSettings: Default invoice settings for this customer. /// - metadata: A set of key-value pairs that you can attach to a customer object. It can be useful for storing additional information about the customer in a structured format. - /// - paymentMethod: ID of the PaymentMethod to attach to the customer + /// - name: The customer’s full name or business name. + /// - phone: The customer’s phone number. + /// - preferredLocales: Customer’s preferred languages, ordered by preference. /// - shipping: The customer’s shipping information. Appears on invoices emailed to this customer. /// - source: The source can be a Token or a Source, as returned by Elements. You must provide a source if the customer does not already have a valid source attached, and you are subscribing the customer to be charged automatically for a plan that is not free. \n Passing source will create a new source object, make it the customer default source, and delete the old customer default if one exists. If you want to add an additional source, instead use the card creation API to add the card and then the customer update API to set it as the default. \n Whenever you attach a card to a customer, Stripe will automatically validate the card. - /// - taxInfo: The customer’s tax information. Appears on invoices emailed to this customer. + /// - taxExempt: The customer’s tax exemption. One of none, exempt, or reverse. /// - Returns: A `StripeCustomer`. func update(customer: String, + address: [String: Any]?, accountBalance: Int?, coupon: String?, defaultSource: String?, @@ -70,9 +84,12 @@ public protocol CustomerRoutes { invoicePrefix: String?, invoiceSettings: [String: Any]?, metadata: [String: String]?, + name: String?, + phone: String?, + preferredLocales: [String]?, shipping: [String: Any]?, source: Any?, - taxInfo: [String: String]?) -> EventLoopFuture + taxExempt: StripeCustomerTaxExempt?) -> EventLoopFuture /// Permanently deletes a customer. It cannot be undone. Also immediately cancels any active subscriptions on the customer. @@ -91,28 +108,38 @@ public protocol CustomerRoutes { } extension CustomerRoutes { - public func create(accountBalance: Int? = nil, + public func create(address: [String: Any]? = nil, + balance: Int? = nil, coupon: String? = nil, description: String? = nil, email: String? = nil, invoicePrefix: String? = nil, invoiceSettings: [String: Any]? = nil, metadata: [String: String]? = nil, + name: String? = nil, paymentMethod: String? = nil, + phone: String? = nil, + preferredLocales: [String]? = nil, shipping: [String: Any]? = nil, source: Any? = nil, - taxInfo: [String: String]? = nil) -> EventLoopFuture { - return create(accountBalance: accountBalance, - coupon: coupon, - description: description, - email: email, - invoicePrefix: invoicePrefix, - invoiceSettings: invoiceSettings, - metadata: metadata, - paymentMethod: paymentMethod, - shipping: shipping, - source: source, - taxInfo: taxInfo) + taxExempt: StripeCustomerTaxExempt? = nil, + taxIdData: [[String: Any]]? = nil) -> EventLoopFuture { + return create(address: address, + balance: balance, + coupon: coupon, + description: description, + email: email, + invoicePrefix: invoicePrefix, + invoiceSettings: invoiceSettings, + metadata: metadata, + name: name, + paymentMethod: paymentMethod, + phone: phone, + preferredLocales: preferredLocales, + shipping: shipping, + source: source, + taxExempt: taxExempt, + taxIdData: taxIdData) } public func retrieve(customer: String) -> EventLoopFuture { @@ -120,7 +147,8 @@ extension CustomerRoutes { } public func update(customer: String, - accountBalance: Int? = nil, + address: [String: Any]? = nil, + balance: Int? = nil, coupon: String? = nil, defaultSource: String? = nil, description: String? = nil, @@ -128,21 +156,28 @@ extension CustomerRoutes { invoicePrefix: String? = nil, invoiceSettings: [String: Any]? = nil, metadata: [String: String]? = nil, + name: String? = nil, + phone: String? = nil, + preferredLocales: [String]? = nil, shipping: [String: Any]? = nil, source: Any? = nil, - taxInfo: [String: String]? = nil) -> EventLoopFuture { + taxExempt: StripeCustomerTaxExempt? = nil) -> EventLoopFuture { return update(customer: customer, - accountBalance: accountBalance, - coupon: coupon, - defaultSource: defaultSource, - description: description, - email: email, - invoicePrefix: invoicePrefix, - invoiceSettings: invoiceSettings, - metadata: metadata, - shipping: shipping, - source: source, - taxInfo: taxInfo) + address: address, + balance: balance, + coupon: coupon, + defaultSource: defaultSource, + description: description, + email: email, + invoicePrefix: invoicePrefix, + invoiceSettings: invoiceSettings, + metadata: metadata, + name: name, + phone: phone, + preferredLocales: preferredLocales, + shipping: shipping, + source: source, + taxExempt: taxExempt) } public func delete(customer: String) -> EventLoopFuture { @@ -163,21 +198,30 @@ public struct StripeCustomerRoutes: CustomerRoutes { self.apiHandler = apiHandler } - public func create(accountBalance: Int?, + public func create(address: [String: Any]?, + balance: Int?, coupon: String?, description: String?, email: String?, invoicePrefix: String?, invoiceSettings: [String: Any]?, metadata: [String: String]?, + name: String?, paymentMethod: String?, + phone: String?, + preferredLocales: [String]?, shipping: [String: Any]?, source: Any?, - taxInfo: [String: String]?) -> EventLoopFuture { + taxExempt: StripeCustomerTaxExempt?, + taxIdData: [[String: Any]]?) -> EventLoopFuture { var body: [String: Any] = [:] - if let accountBalance = accountBalance { - body["account_balance"] = accountBalance + if let address = address { + address.forEach { body["address[\($0)]"] = $1 } + } + + if let balance = balance { + body["balance"] = balance } if let coupon = coupon { @@ -204,10 +248,22 @@ public struct StripeCustomerRoutes: CustomerRoutes { metadata.forEach { body["metadata[\($0)]"] = $1 } } + if let name = name { + body["name"] = name + } + if let paymentMethod = paymentMethod { body["payment_method"] = paymentMethod } + if let phone = phone { + body["phone"] = phone + } + + if let preferredLocales = preferredLocales { + body["preferred_locales"] = preferredLocales + } + if let shipping = shipping { shipping.forEach { body["shipping[\($0)]"] = $1 } } @@ -220,8 +276,12 @@ public struct StripeCustomerRoutes: CustomerRoutes { hashSource.forEach { body["source[\($0)]"] = $1 } } - if let taxInfo = taxInfo { - taxInfo.forEach { body["tax_info[\($0)]"] = $1 } + if let taxExempt = taxExempt { + body["tax_exempt"] = taxExempt.rawValue + } + + if let taxIdData = taxIdData { + body["tax_id_data"] = taxIdData } return apiHandler.send(method: .POST, path: StripeAPIEndpoint.customers.endpoint, body: .string(body.queryParameters), headers: headers) @@ -232,6 +292,7 @@ public struct StripeCustomerRoutes: CustomerRoutes { } public func update(customer: String, + address: [String: Any]?, accountBalance: Int?, coupon: String?, defaultSource: String?, @@ -240,13 +301,20 @@ public struct StripeCustomerRoutes: CustomerRoutes { invoicePrefix: String?, invoiceSettings: [String: Any]?, metadata: [String: String]?, + name: String?, + phone: String?, + preferredLocales: [String]?, shipping: [String: Any]?, source: Any?, - taxInfo: [String: String]?) -> EventLoopFuture { + taxExempt: StripeCustomerTaxExempt?) -> EventLoopFuture { var body: [String: Any] = [:] - if let accountBalance = accountBalance { - body["account_balance"] = accountBalance + if let address = address { + address.forEach { body["address[\($0)]"] = $1 } + } + + if let balance = balance { + body["balance"] = balance } if let coupon = coupon { @@ -277,6 +345,18 @@ public struct StripeCustomerRoutes: CustomerRoutes { metadata.forEach { body["metadata[\($0)]"] = $1 } } + if let name = name { + body["name"] = name + } + + if let phone = phone { + body["phone"] = phone + } + + if let preferredLocales = preferredLocales { + body["preferred_locales"] = preferredLocales + } + if let shipping = shipping { shipping.forEach { body["shipping[\($0)]"] = $1 } } @@ -289,8 +369,8 @@ public struct StripeCustomerRoutes: CustomerRoutes { hashSource.forEach { body["source[\($0)]"] = $1 } } - if let taxInfo = taxInfo { - taxInfo.forEach { body["tax_info[\($0)]"] = $1 } + if let taxExempt = taxExempt { + body["tax_exempt"] = taxExempt.rawValue } return apiHandler.send(method: .POST, path: StripeAPIEndpoint.customer(customer).endpoint, body: .string(body.queryParameters), headers: headers) diff --git a/Sources/StripeKit/API/Routes/SubscriptionRoutes.swift b/Sources/StripeKit/API/Routes/SubscriptionRoutes.swift index 93834258..df869270 100644 --- a/Sources/StripeKit/API/Routes/SubscriptionRoutes.swift +++ b/Sources/StripeKit/API/Routes/SubscriptionRoutes.swift @@ -16,10 +16,10 @@ public protocol SubscriptionRoutes { /// - Parameters: /// - customer: The identifier of the customer to subscribe. /// - applicationFeePercent: A non-negative decimal between 0 and 100, with at most two decimal places. This represents the percentage of the subscription invoice subtotal that will be transferred to the application owner’s Stripe account. The request must be made with an OAuth key in order to set an application fee percentage. For more information, see the application fees documentation. - /// - billing: Either `charge_automatically`, or `send_invoice`. When charging automatically, Stripe will attempt to pay this subscription at the end of the cycle using the default source attached to the customer. When sending an invoice, Stripe will email your customer an invoice with payment instructions. Defaults to `charge_automatically`. /// - billingCycleAnchor: A future timestamp to anchor the subscription’s [billing cycle](https://stripe.com/docs/subscriptions/billing-cycle). This is used to determine the date of the first full invoice, and, for plans with `month` or `year` intervals, the day of the month for subsequent invoices. /// - billingThresholds: Define thresholds at which an invoice will be sent, and the subscription advanced to a new billing period. Pass an empty string to remove previously-defined thresholds. /// - cancelAtPeriodEnd: Boolean indicating whether this subscription should cancel at the end of the current period. + /// - collectionMethod: Either `charge_automatically`, or `send_invoice`. When charging automatically, Stripe will attempt to pay this subscription at the end of the cycle using the default source attached to the customer. When sending an invoice, Stripe will email your customer an invoice with payment instructions. Defaults to `charge_automatically`. /// - coupon: The code of the coupon to apply to this subscription. A coupon applied to a subscription will only affect invoices created for that particular subscription. This will be unset if you POST an empty value. /// - daysUntilDue: Number of days a customer has to pay invoices generated by this subscription. Valid only for subscriptions where `billing` is set to `send_invoice`. /// - defaultPaymentMethod: ID of the default payment method for the subscription. It must belong to the customer associated with the subscription. If not set, invoices will use the default payment method in the customer’s invoice settings. @@ -27,6 +27,9 @@ public protocol SubscriptionRoutes { /// - defaultTaxRates: The tax rates that will apply to any subscription item that does not have `tax_rates` set. Invoices created will have their `default_tax_rates` populated from the subscription. /// - items: List of subscription items, each with an attached plan. /// - metadata: A set of key-value pairs that you can attach to a Subscription object. It can be useful for storing additional information about the subscription in a structured format. + /// - offSession: Indicates if a customer is on or off-session while an invoice payment is attempted. + /// - paymentBehavior: Use `allow_incomplete` to create subscriptions with `status=incomplete` if its first invoice cannot be paid. Creating subscriptions with this status allows you to manage scenarios where additional user actions are needed to pay a subscription’s invoice. For example, SCA regulation may require 3DS authentication to complete payment. See the [SCA Migration Guide](https://stripe.com/docs/billing/migration/strong-customer-authentication) for Billing to learn more. This is the default behavior. Use `error_if_incomplete` if you want Stripe to return an HTTP 402 status code if a subscription’s first invoice cannot be paid. For example, if a payment method requires 3DS authentication due to SCA regulation and further user action is needed, this parameter does not create a subscription and returns an error instead. This was the default behavior for API versions prior to 2019-03-14. See the [changelog](https://stripe.com/docs/upgrades#2019-03-14) to learn more. + /// - pendingInvoiceItemInterval: Specifies an interval for how often to bill for any pending invoice items. It is analogous to calling [Create an invoice](https://stripe.com/docs/api#create_invoice) for the given subscription at the specified interval. /// - prorate: Boolean (defaults to `true`) telling us whether to [credit for unused time](https://stripe.com/docs/subscriptions/billing-cycle#prorations) when the billing cycle changes (e.g. when switching plans, resetting `billing_cycle_anchor=now`, or starting a trial), or if an item’s `quantity` changes. If `false`, the anchor period will be free (similar to a trial) and no proration adjustments will be created. /// - trialEnd: Unix timestamp representing the end of the trial period the customer will get before being charged for the first time. This will always overwrite any trials that might apply via a subscribed plan. If set, trial_end will override the default trial period of the plan the customer is being subscribed to. The special value now can be provided to end the customer’s trial immediately. Can be at most two years from `billing_cycle_anchor`. /// - trialFromPlan: Indicates if a plan’s trial_period_days should be applied to the subscription. Setting trial_end per subscription is preferred, and this defaults to false. Setting this flag to true together with trial_end is not allowed. @@ -34,10 +37,10 @@ public protocol SubscriptionRoutes { /// - Returns: A `StripeSubscription`. func create(customer: String, applicationFeePercent: Decimal?, - billing: StripeInvoiceBiling?, billingCycleAnchor: Date?, billingThresholds: [String: Any]?, cancelAtPeriodEnd: Bool?, + collectionMethod: StripeInvoiceBiling?, coupon: String?, daysUntilDue: Int?, defaultPaymentMethod: String?, @@ -45,6 +48,9 @@ public protocol SubscriptionRoutes { defaultTaxRates: [String]?, items: [[String: Any]]?, metadata: [String: String]?, + offSession: Bool?, + paymentBehavior: StripeSubscriptionPaymentBehavior?, + pendingInvoiceItemInterval: [String: Any]?, prorate: Bool?, trialEnd: Any?, trialFromPlan: Bool?, @@ -61,10 +67,10 @@ public protocol SubscriptionRoutes { /// - Parameters: /// - subscription: The ID of the subscription to update. /// - applicationFeePercent: A non-negative decimal between 0 and 100, with at most two decimal places. This represents the percentage of the subscription invoice subtotal that will be transferred to the application owner’s Stripe account. The request must be made with an OAuth key in order to set an application fee percentage. For more information, see the application fees documentation. - /// - billing: Either `charge_automatically`, or `send_invoice`. When charging automatically, Stripe will attempt to pay this subscription at the end of the cycle using the default source attached to the customer. When sending an invoice, Stripe will email your customer an invoice with payment instructions. Defaults to `charge_automatically`. /// - billingCycleAnchor: Either `now` or `unchanged`. Setting the value to now resets the subscription’s billing cycle anchor to the current time. For more information, see the billing cycle documentation. /// - billingThresholds: Define thresholds at which an invoice will be sent, and the subscription advanced to a new billing period. Pass an empty string to remove previously-defined thresholds. /// - cancelAtPeriodEnd: Boolean indicating whether this subscription should cancel at the end of the current period. + /// - collectionMethod: Either `charge_automatically`, or `send_invoice`. When charging automatically, Stripe will attempt to pay this subscription at the end of the cycle using the default source attached to the customer. When sending an invoice, Stripe will email your customer an invoice with payment instructions. Defaults to `charge_automatically`. /// - coupon: The code of the coupon to apply to this subscription. A coupon applied to a subscription will only affect invoices created for that particular subscription. This will be unset if you POST an empty value. /// - daysUntilDue: Number of days a customer has to pay invoices generated by this subscription. Valid only for subscriptions where billing is set to send_invoice. /// - defaultPaymentMethod: ID of the default payment method for the subscription. It must belong to the customer associated with the subscription. If not set, invoices will use the default payment method in the customer’s invoice settings. @@ -72,6 +78,9 @@ public protocol SubscriptionRoutes { /// - defaultTaxRates: The tax rates that will apply to any subscription item that does not have tax_rates set. Invoices created will have their default_tax_rates populated from the subscription. /// - items: List of subscription items, each with an attached plan. /// - metadata: A set of key-value pairs that you can attach to a subscription object. This can be useful for storing additional information about the subscription in a structured format. + /// - offSession: Indicates if a customer is on or off-session while an invoice payment is attempted. + /// - paymentBehavior: Use `allow_incomplete` to create subscriptions with `status=incomplete` if its first invoice cannot be paid. Creating subscriptions with this status allows you to manage scenarios where additional user actions are needed to pay a subscription’s invoice. For example, SCA regulation may require 3DS authentication to complete payment. See the [SCA Migration Guide](https://stripe.com/docs/billing/migration/strong-customer-authentication) for Billing to learn more. This is the default behavior. Use `error_if_incomplete` if you want Stripe to return an HTTP 402 status code if a subscription’s first invoice cannot be paid. For example, if a payment method requires 3DS authentication due to SCA regulation and further user action is needed, this parameter does not create a subscription and returns an error instead. This was the default behavior for API versions prior to 2019-03-14. See the [changelog](https://stripe.com/docs/upgrades#2019-03-14) to learn more. + /// - pendingInvoiceItemInterval: Specifies an interval for how often to bill for any pending invoice items. It is analogous to calling [Create an invoice](https://stripe.com/docs/api#create_invoice) for the given subscription at the specified interval. /// - prorate: Boolean (defaults to `true`) telling us whether to [credit for unused time](https://stripe.com/docs/subscriptions/billing-cycle#prorations) when the billing cycle changes (e.g. when switching plans, resetting `billing_cycle_anchor=now`, or starting a trial), or if an item’s `quantity` changes. If `false`, the anchor period will be free (similar to a trial) and no proration adjustments will be created. /// - prorationDate: If set, the proration will be calculated as though the subscription was updated at the given time. This can be used to apply exactly the same proration that was previewed with [upcoming invoice](https://stripe.com/docs/api/subscriptions/update#retrieve_customer_invoice) endpoint. It can also be used to implement custom proration logic, such as prorating by day instead of by second, by providing the time that you wish to use for proration calculations. /// - trialEnd: Unix timestamp representing the end of the trial period the customer will get before being charged for the first time. This will always overwrite any trials that might apply via a subscribed plan. If set, trial_end will override the default trial period of the plan the customer is being subscribed to. The special value `now` can be provided to end the customer’s trial immediately. Can be at most two years from `billing_cycle_anchor`. @@ -79,10 +88,10 @@ public protocol SubscriptionRoutes { /// - Returns: A `StripeSubscription`. func update(subscription: String, applicationFeePercent: Decimal?, - billing: StripeInvoiceBiling?, billingCycleAnchor: String?, billingThresholds: [String: Any]?, cancelAtPeriodEnd: Bool?, + collectionMethod: StripeInvoiceBiling?, coupon: String?, daysUntilDue: Int?, defaultPaymentMethod: String?, @@ -90,6 +99,9 @@ public protocol SubscriptionRoutes { defaultTaxRates: [String]?, items: [[String: Any]]?, metadata: [String: String]?, + offSession: Bool?, + paymentBehavior: StripeSubscriptionPaymentBehavior?, + pendingInvoiceItemInterval: [String: Any]?, prorate: Bool?, prorationDate: Date?, trialEnd: Any?, @@ -117,10 +129,10 @@ public protocol SubscriptionRoutes { extension SubscriptionRoutes { public func create(customer: String, applicationFeePercent: Decimal? = nil, - billing: StripeInvoiceBiling? = nil, billingCycleAnchor: Date? = nil, billingThresholds: [String: Any]? = nil, cancelAtPeriodEnd: Bool? = nil, + collectionMethod: StripeInvoiceBiling? = nil, coupon: String? = nil, daysUntilDue: Int? = nil, defaultPaymentMethod: String? = nil, @@ -128,16 +140,19 @@ extension SubscriptionRoutes { defaultTaxRates: [String]? = nil, items: [[String: Any]]? = nil, metadata: [String: String]? = nil, + offSession: Bool? = nil, + paymentBehavior: StripeSubscriptionPaymentBehavior? = nil, + pendingInvoiceItemInterval: [String: Any]? = nil, prorate: Bool? = nil, trialEnd: Any? = nil, trialFromPlan: Bool? = nil, trialPeriodDays: Int? = nil) -> EventLoopFuture { return create(customer: customer, applicationFeePercent: applicationFeePercent, - billing: billing, billingCycleAnchor: billingCycleAnchor, billingThresholds: billingThresholds, cancelAtPeriodEnd: cancelAtPeriodEnd, + collectionMethod: collectionMethod, coupon: coupon, daysUntilDue: daysUntilDue, defaultPaymentMethod: defaultPaymentMethod, @@ -145,6 +160,9 @@ extension SubscriptionRoutes { defaultTaxRates: defaultTaxRates, items: items, metadata: metadata, + offSession: offSession, + paymentBehavior: paymentBehavior, + pendingInvoiceItemInterval: pendingInvoiceItemInterval, prorate: prorate, trialEnd: trialEnd, trialFromPlan: trialFromPlan, @@ -157,10 +175,10 @@ extension SubscriptionRoutes { public func update(subscription: String, applicationFeePercent: Decimal? = nil, - billing: StripeInvoiceBiling? = nil, billingCycleAnchor: String? = nil, billingThresholds: [String: Any]? = nil, cancelAtPeriodEnd: Bool? = nil, + collectionMethod: StripeInvoiceBiling? = nil, coupon: String? = nil, daysUntilDue: Int? = nil, defaultPaymentMethod: String? = nil, @@ -168,16 +186,19 @@ extension SubscriptionRoutes { defaultTaxRates: [String]? = nil, items: [[String: Any]]? = nil, metadata: [String: String]? = nil, + offSession: Bool? = nil, + paymentBehavior: StripeSubscriptionPaymentBehavior? = nil, + pendingInvoiceItemInterval: [String: Any]? = nil, prorate: Bool? = nil, prorationDate: Date? = nil, trialEnd: Any? = nil, trialFromPlan: Bool? = nil) -> EventLoopFuture { return update(subscription: subscription, applicationFeePercent: applicationFeePercent, - billing: billing, billingCycleAnchor: billingCycleAnchor, billingThresholds: billingThresholds, cancelAtPeriodEnd: cancelAtPeriodEnd, + collectionMethod: collectionMethod, coupon: coupon, daysUntilDue: daysUntilDue, defaultPaymentMethod: defaultPaymentMethod, @@ -185,6 +206,9 @@ extension SubscriptionRoutes { defaultTaxRates: defaultTaxRates, items: items, metadata: metadata, + offSession: offSession, + paymentBehavior: paymentBehavior, + pendingInvoiceItemInterval: pendingInvoiceItemInterval, prorate: prorate, prorationDate: prorationDate, trialEnd: trialEnd, @@ -214,6 +238,7 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { billingCycleAnchor: Date?, billingThresholds: [String: Any]?, cancelAtPeriodEnd: Bool?, + collectionMethod: StripeInvoiceBiling?, coupon: String?, daysUntilDue: Int?, defaultPaymentMethod: String?, @@ -221,6 +246,9 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { defaultTaxRates: [String]?, items: [[String: Any]]?, metadata: [String: String]?, + offSession: Bool?, + paymentBehavior: StripeSubscriptionPaymentBehavior?, + pendingInvoiceItemInterval: [String: Any]?, prorate: Bool?, trialEnd: Any?, trialFromPlan: Bool?, @@ -231,10 +259,6 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { body["application_fee_percent"] = applicationFeePercent } - if let billing = billing { - body["billing"] = billing.rawValue - } - if let billingCycleAnchor = billingCycleAnchor { body["billing_cycle_anchor"] = Int(billingCycleAnchor.timeIntervalSince1970) } @@ -247,6 +271,10 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { body["cancel_at_period_end"] = cancelAtPeriodEnd } + if let collectionMethod = collectionMethod { + body["collection_method"] = collectionMethod.rawValue + } + if let coupon = coupon { body["coupon"] = coupon } @@ -275,6 +303,18 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { metadata.forEach { body["metadata[\($0)]"] = $1 } } + if let offSession = offSession { + body["off_session"] = offSession + } + + if let paymentBehavior = paymentBehavior { + body["payment_behavior"] = paymentBehavior.rawValue + } + + if let pendingInvoiceItemInterval = pendingInvoiceItemInterval { + pendingInvoiceItemInterval.forEach { body["pending_invoice_item_interval[\($0)]"] = $1 } + } + if let prorate = prorate { body["prorate"] = prorate } @@ -304,10 +344,10 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { public func update(subscription: String, applicationFeePercent: Decimal?, - billing: StripeInvoiceBiling?, billingCycleAnchor: String?, billingThresholds: [String: Any]?, cancelAtPeriodEnd: Bool?, + collectionMethod: StripeInvoiceBiling?, coupon: String?, daysUntilDue: Int?, defaultPaymentMethod: String?, @@ -315,6 +355,9 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { defaultTaxRates: [String]?, items: [[String: Any]]?, metadata: [String: String]?, + offSession: Bool?, + paymentBehavior: StripeSubscriptionPaymentBehavior?, + pendingInvoiceItemInterval: [String: Any]?, prorate: Bool?, prorationDate: Date?, trialEnd: Any?, @@ -325,10 +368,6 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { body["application_fee_percent"] = applicationFeePercent } - if let billing = billing { - body["billing"] = billing.rawValue - } - if let billingCycleAnchor = billingCycleAnchor { body["billing_cycle_anchor"] = billingCycleAnchor } @@ -341,6 +380,10 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { body["cancel_at_period_end"] = cancelAtPeriodEnd } + if let collectionMethod = collectionMethod { + body["collection_method"] = collectionMethod.rawValue + } + if let coupon = coupon { body["coupon"] = coupon } @@ -369,6 +412,18 @@ public struct StripeSubscriptionRoutes: SubscriptionRoutes { metadata.forEach { body["metadata[\($0)]"] = $1 } } + if let offSession = offSession { + body["off_session"] = offSession + } + + if let paymentBehavior = paymentBehavior { + body["payment_behavior"] = paymentBehavior.rawValue + } + + if let pendingInvoiceItemInterval = pendingInvoiceItemInterval { + pendingInvoiceItemInterval.forEach { body["pending_invoice_item_interval[\($0)]"] = $1 } + } + if let prorate = prorate { body["prorate"] = prorate } diff --git a/Sources/StripeKit/API/StripeRequest.swift b/Sources/StripeKit/API/StripeRequest.swift index 2539e2ef..3091a1bc 100644 --- a/Sources/StripeKit/API/StripeRequest.swift +++ b/Sources/StripeKit/API/StripeRequest.swift @@ -52,7 +52,7 @@ public struct StripeDefaultAPIHandler: StripeAPIHandler { body: HTTPClient.Body = .string(""), headers: HTTPHeaders = [:]) -> EventLoopFuture { - var _headers: HTTPHeaders = ["Stripe-Version": "2019-10-08", + var _headers: HTTPHeaders = ["Stripe-Version": "2019-11-05", "Authorization": "Bearer \(apiKey)", "Content-Type": "application/x-www-form-urlencoded"] headers.forEach { _headers.replaceOrAdd(name: $0.name, value: $0.value) } diff --git a/Sources/StripeKit/Models/Billing/Subscriptions/Subscription.swift b/Sources/StripeKit/Models/Billing/Subscriptions/Subscription.swift index d0125c2e..af2b6a8b 100644 --- a/Sources/StripeKit/Models/Billing/Subscriptions/Subscription.swift +++ b/Sources/StripeKit/Models/Billing/Subscriptions/Subscription.swift @@ -16,8 +16,6 @@ public struct StripeSubscription: StripeModel { public var object: String /// A non-negative decimal between 0 and 100, with at most two decimal places. This represents the percentage of the subscription invoice subtotal that will be transferred to the application owner’s Stripe account. public var applicationFeePercent: Decimal? - /// Either `charge_automatically`, or `send_invoice`. When charging automatically, Stripe will attempt to pay this subscription at the end of the cycle using the default source attached to the customer. When sending an invoice, Stripe will email your customer an invoice with payment instructions. - public var billing: StripeInvoiceBiling? /// Determines the date of the first full invoice, and, for plans with `month` or `year` intervals, the day of the month for subsequent invoices. public var billingCycleAnchor: Date? /// Define thresholds at which an invoice will be sent, and the subscription advanced to a new billing period @@ -26,6 +24,8 @@ public struct StripeSubscription: StripeModel { public var cancelAtPeriodEnd: Bool? /// If the subscription has been canceled, the date of that cancellation. If the subscription was canceled with `cancel_at_period_end`, `canceled_at` will still reflect the date of the initial cancellation request, not the end of the subscription period when the subscription is automatically moved to a canceled state. public var canceledAt: Date? + /// Either `charge_automatically`, or `send_invoice`. When charging automatically, Stripe will attempt to pay this subscription at the end of the cycle using the default source attached to the customer. When sending an invoice, Stripe will email your customer an invoice with payment instructions. + public var collectionMethod: StripeInvoiceBiling? /// Time at which the object was created. Measured in seconds since the Unix epoch. public var created: Date? /// End of the current period that the subscription has been invoiced for. At the end of this period, a new invoice will be created. @@ -46,6 +46,8 @@ public struct StripeSubscription: StripeModel { public var discount: StripeDiscount? /// If the subscription has ended, the date the subscription ended. public var endedAt: Date? + /// Settings controlling the behavior of applied customer balances on invoices generated by this subscription. + public var invoiceCustomerBalanceSettings: StripeSubscriptionInvoiceCustomerBalanceSettings? /// List of subscription items, each with an attached plan. public var items: StripeSubscriptionItemList? /// The most recent invoice this subscription has generated. @@ -54,6 +56,12 @@ public struct StripeSubscription: StripeModel { public var livemode: Bool? /// Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. public var metadata: [String: String]? + /// Specifies the approximate timestamp on which any pending invoice items will be billed according to the schedule provided at pending_invoice_item_interval. + public var nextPendingInvoiceItemInvoice: Date? + /// Specifies an interval for how often to bill for any pending invoice items. It is analogous to calling Create an invoice for the given subscription at the specified interval. + public var pendingInvoiceItemInterval: StripeSubscriptionPendingInvoiceInterval? + /// You can use this SetupIntent to collect user authentication when creating a subscription without immediate payment or updating a subscription’s payment method, allowing you to optimize for off-session payments. Learn more in the SCA Migration Guide. + public var pendingSetupIntent: String /// Hash describing the plan the customer is subscribed to. Only set if the subscription contains a single plan. public var plan: StripePlan? /// The quantity of the plan to which the customer is subscribed. For example, if your plan is $10/user/month, and your customer has 5 users, you could pass 5 as the quantity to have the customer charged $50 (5 x $10) monthly. Only set if the subscription contains a single plan. @@ -75,6 +83,13 @@ public struct StripeSubscriptionBillingThresholds: StripeModel { public var resetBillingCycleAnchor: Bool? } +public struct StripeSubscriptionPendingInvoiceInterval: StripeModel { + /// Specifies invoicing frequency. Either `day`, `week`, `month` or `year`. + public var interval: StripePlanInterval? + /// The number of intervals between invoices. For example, `interval=month` and `interval_count=3` bills every 3 months. Maximum of one year interval allowed (1 year, 12 months, or 52 weeks). + public var intervalCount: Int? +} + public enum StripeSubscriptionStatus: String, StripeModel { case incomplete case incompleteExpired = "incomplete_expired" @@ -91,3 +106,13 @@ public struct StripeSubscriptionList: StripeModel { public var url: String? public var data: [StripeSubscription]? } + +public struct StripeSubscriptionInvoiceCustomerBalanceSettings: StripeModel { + /// Controls whether a customer balance applied to this invoice should be consumed and not credited or debited back to the customer if voided. + public var consumeAppliedBalanceOnVoid: Bool? +} + +public enum StripeSubscriptionPaymentBehavior: String, StripeModel { + case allowComplete = "allow_complete" + case errorIfIncomplete = "error_if_complete" +} diff --git a/Sources/StripeKit/Models/Core Resources/Customers/Customer.swift b/Sources/StripeKit/Models/Core Resources/Customers/Customer.swift index a21fab60..9f0295de 100644 --- a/Sources/StripeKit/Models/Core Resources/Customers/Customer.swift +++ b/Sources/StripeKit/Models/Core Resources/Customers/Customer.swift @@ -14,8 +14,10 @@ public struct StripeCustomer: StripeModel { public var id: String /// String representing the object’s type. Objects of the same type share the same value. public var object: String + /// The customers address. + public var addrress: StripeAddress? /// Current balance, if any, being stored on the customer’s account. If negative, the customer has credit to apply to the next invoice. If positive, the customer has an amount owed that will be added to the next invoice. The balance does not refer to any unpaid invoices; it solely takes into account amounts that have yet to be successfully applied to any invoice. This balance is only taken into account as invoices are finalized. Note that the balance does not include unpaid invoices. - public var accountBalance: Int? + public var balance: Int? /// Time at which the object was created. Measured in seconds since the Unix epoch. public var created: Date? /// Three-letter ISO code for the currency the customer can be charged in for recurring billing purposes. @@ -38,16 +40,22 @@ public struct StripeCustomer: StripeModel { public var livemode: Bool? /// Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. public var metadata: [String: String]? + /// The customers full name or business name. + public var name: String? + /// The customers phone number. + public var phone: String? + /// The customer’s preferred locales (languages), ordered by preference + public var preferredLocals: [String]? /// Mailing and shipping address for the customer. Appears on invoices emailed to this customer. public var shipping: StripeShippingLabel? /// The customer’s payment sources, if any. public var sources: StripeSourcesList? /// The customer’s current subscriptions, if any. public var subscriptions: StripeSubscriptionList? - /// The customer’s tax information. Appears on invoices emailed to this customer. - public var taxInfo: StripeCustomerTaxInfo? - /// Describes the status of looking up the tax ID provided in `tax_info`. - public var taxInfoVerification: StripeCustomerTaxInfoVerification? + /// Describes the customer’s tax exemption status. One of `none`, `exempt`, or `reverse`. When set to `reverse`, invoice and receipt PDFs include the text `“Reverse charge”`. + public var taxExempt: StripeCustomerTaxExempt? + /// The customers tax IDs + public var taxIds: StripeTaxIDList? } public struct StripeCustomerInvoiceSettings: StripeModel { @@ -64,24 +72,10 @@ public struct StripeCustomerInvoiceSettingsCustomFields: StripeModel { public var value: String? } -public struct StripeCustomerTaxInfo: StripeModel { - /// The customer’s tax ID number. - public var taxId: String? - /// The type of ID number. - public var type: String? -} - -public struct StripeCustomerTaxInfoVerification: StripeModel { - /// The state of verification for this customer. Possible values are `unverified`, `pending`, or `verified`. - public var status: StripeCustomerTaxInfoVerificationStatus? - /// The official name associated with the tax ID returned from the external provider. - public var verifiedName: String? -} - -public enum StripeCustomerTaxInfoVerificationStatus: String, StripeModel { - case unverified - case pending - case verified +public enum StripeCustomerTaxExempt: String, StripeModel { + case none + case exempt + case reverse } public struct StripeCustomerList: StripeModel { From 16cd691d7ce58d3ac6b16ed36a2f608bfd869975 Mon Sep 17 00:00:00 2001 From: Andrew Edwards Date: Tue, 5 Nov 2019 21:41:01 -0500 Subject: [PATCH 3/3] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 36c20cc8..18c8602e 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,14 @@ ### StripeKit is a Swift package used to communicate with the [Stripe](https://stripe.com) API for Server Side Swift Apps. ## Current supported version -Version **1.0.0** of StripeKit supports the Stripe API version of **[2019-05-16](https://stripe.com/docs/upgrades#2019-05-16)**. -You can check the releases page to use a version of StripeKit that meets your needs. +Version **2.0.0** of StripeKit supports the Stripe API version of **[2019-11-05](https://stripe.com/docs/upgrades#2019-11-05)**. +**You can check the releases page to use a version of StripeKit that meets your needs.** ## Installation To start using StripeKit, in your `Package.swift`, add the following ~~~~swift -.package(url: "https://github.com/vapor-community/stripekit.git", from: "1.0.0") +.package(url: "https://github.com/vapor-community/stripekit.git", from: "2.0.0") ~~~~ ## Using the API