Swiftpack.co - Package - vapor-community/StripeKit

StripeKit

StripeKit is a Swift package used to communicate with the Stripe API for Server Side Swift Apps.

Current supported version

Version 5.0.0 of StripeKit supports the Stripe API version of 2019-12-03. 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

.package(url: "https://github.com/vapor-community/stripekit.git", from: "5.0.0")

Using the API

Initialize the StripeClient

let httpClient = HTTPClient(..)
let stripe = StripeClient(httpClient: httpClient, eventLoop: eventLoop, apiKey: "sk_12345")

And now you have acess to the APIs via stripe.

The APIs you have available correspond to what's implemented.

For example to use the charges API, the stripeclient has a property to access that API via routes.

 stripe.charges.create(amount: 2500,
                       currency: .usd,
		       description: "A server written in swift.",
                       source: "tok_visa").flatMap { (charge) -> EventLoopFuture<Void> in
                          if charge.status == .succeeded {
                              print("New servers are on the way 🚀")
                          } else {
                              print("Sorry you have to use Node.js 🤢")
                          }
            }

Nuances with parameters and type safety

Stripe has a habit of changing APIs and having dynamic parameters for a lot of their APIs. To accomadate for these changes, certain routes that take arguments that are hashs or Dictionaries, are represented by a Swift dictionary [String: Any].

For example consider the Connect account API.

// We define a custom dictionary to represent the paramaters stripe requires.
// This allows us to avoid having to add updates to the library when a paramater or structure changes.
let individual: [String: Any] = ["address": ["city": "New York",
					     "country": "US",
                                             "line1": "1551 Broadway",
                                             "postal_code": "10036",
	                  	             "state": "NY"],
				 "first_name": "Taylor",
			         "last_name": "Swift",
                                 "ssn_last_4": "0000",
				 "dob": ["day": "13",
					 "month": "12",
					 "year": "1989"]]
												 
let businessSettings: [String: Any] = ["payouts": ["statement_descriptor": "SWIFTFORALL"]]

let tosDictionary: [String: Any] = ["date": Int(Date().timeIntervalSince1970), "ip": "127.0.0.1"]

    stripe.connectAccounts.create(type: .custom,									
                                  country: "US",
				  email: "a@example.com",
				  businessType: .individual,
			          defaultCurrency: .usd,
				  externalAccount: "bank_token",
			          individual: individual,
				  requestedCapabilities: ["platform_payments"],
				  settings: businessSettings,
				  tosAcceptance: tosDictionary).flatMap { connectAccount in
					print("New Stripe Connect account ID: \(connectAccount.id)")			
				}

Authentication via the Stripe-Account header

The first, preferred, authentication option is to use your (the platform account’s) secret key and pass a Stripe-Account header identifying the connected account for which the request is being made. The example request performs a refund of a charge on behalf of a connected account:

   stripe.refunds.headers.add(name: "Stripe-Account", value: "acc_12345")
   stripe.refunds.create(charge: "ch_12345", reason: .requestedByCustomer)

NOTE: The modified headers will remain on the route instance (refunds in this case) of the StripeClient if a reference to it is held. If you're accessing the StripeClient in the scope of a function, the headers will not be retained.

Error Handling

None of the API calls throw errors. Instead each route returns a successful EventLoopFuture or a failed EventLoopFuture.

 stripe.charges.create(amount: 2500,
                       currency: .usd,
		       description: "A server written in swift.",
                       source: "tok_visa")
 .flatMap { (charge) -> EventLoopFuture<Void> in
	  if charge.status == .succeeded {
	      print("New servers are on the way 🚀")
	  } else {
	      print("Sorry you have to use Node.js 🤢")
	  }
  }
  .flatMapError { error in
     print("Stripe error \(error.message)")
  }

Vapor Integration

To use StripeKit with Vapor 4.x, add a simple extension on Request.

extension Request {
    public var stripe: StripeClient {
        return StripeClient(httpClient: self.application.client.http, eventLoop: self.eventLoop, apiKey: "STRIPE_API_KEY")
    }
}

// Later...

func charge(req: Request) -> EventLoopFuture<Response> {
    return req.stripe.charge(...)
}

Whats Implemented

Core Resources

  • [x] Balance
  • [x] Balance Transactions
  • [x] Charges
  • [x] Customers
  • [x] Disputes
  • [x] Events
  • [x] Files
  • [x] File Links
  • [x] Mandates
  • [x] PaymentIntents
  • [x] SetupIntents
  • [x] Payouts
  • [x] Products
  • [x] Refunds
  • [x] Tokens

Payment Methods

  • [x] Payment Methods
  • [x] Bank Accounts
  • [x] Cards
  • [x] Sources

Checkout

  • [x] Sessions

Billing

  • [x] Coupons
  • [x] Credit Notes
  • [x] Customer Balance Transactions
  • [x] Customer Tax IDs
  • [x] Discounts
  • [x] Invoices
  • [x] Invoice Items
  • [x] Plans
  • [x] Products
  • [x] Subscriptions
  • [x] Subscription items
  • [x] Subscription Schedule
  • [x] Tax Rates
  • [x] Usage Records

Connect

  • [x] Account
  • [x] Account Links
  • [x] Application Fees
  • [x] Application Fee Refunds
  • [x] Capabilities
  • [x] Country Specs
  • [x] External Accounts
  • [x] Persons
  • [x] Top-ups
  • [x] Transfers
  • [x] Transfer Reversals

Fraud

  • [x] Early Fraud Warnings
  • [x] Reviews
  • [x] Value Lists
  • [x] Value List Items

Issuing

  • [x] Authorizations
  • [x] Cardholders
  • [x] Cards
  • [x] Disputes
  • [x] Transactions

Terminal

  • [x] Connection Tokens
  • [x] Locations
  • [x] Readers

Orders

  • [x] Orders
  • [x] Order Items
  • [x] Returns
  • [x] SKUs
  • [x] Ephemeral Keys

Sigma

  • [x] Scheduled Queries

Reporting

  • [x] Report Runs
  • [x] Report Types

Webhooks

  • [x] Webhook Endpoints

TODO At some point

License

StripeKit is available under the MIT license. See the LICENSE file for more info.

Want to help?

Feel free to submit a pull request whether it's a clean up, a new approach to handling things, adding a new part of the API, or even if it's just a typo. All help is welcomed! 😀

Github

link
Stars: 27

Used By

Total: 0

Releases

StripeKit 5.0.0 - 2020-01-06 22:29:31

StripeKit 5.0.0 💳🎉

This release of StripeKit marks the completion of the full implementation of Stripes API. The release also pins to the 2019-12-03 API version.

More about issues resolved with the release are here #21

StripeKit 4.0.0 - 2019-12-26 21:14:11

⚠️Breaking changes⚠️

This release allows initializing a StripeClient with a preconfigured HTTPClient and a specified EventLoop to have internal API requests/work to be executed and have EventLoopFutures returned on.

let specialConfig = HTTPClient.Configuration(....)
let client = HTTPClient(specialConfig)
let stripe = StripeClient(httpClient: client, eventLoop: myEventLoop, apiKey: "sk_123")

StripeKit 3.0.2 - 2019-12-13 13:46:42

The release adds some missing TaxID types.

StripeKit 3.0.1 - 2019-12-09 23:09:36

This patch release fixes https://github.com/vapor-community/StripeKit/pull/13

StripeKit 3.0.0 - 2019-12-03 23:40:53

StripeKit 2.0.1 - 2019-11-06 03:00:31

Fixed a typo in customer update routes.

StripeKit 2.0.0 - 2019-11-06 02:43:08

Updated to support the latest 2019-11-05 API.

StripeKit 1.0.11 - 2019-11-03 06:46:36

Use release version of AsyncHttpClient.

StripeKit 1.0.10 - 2019-10-18 19:31:17

Fixed decoding for an optional property.

StripeKit 1.0.9 - 2019-10-06 18:44:29

Fixes an issue where we weren't shutting down the AsyncHTTPClient on deinit

StripeKit 1.0.8 - 2019-08-11 00:11:15

Fixed issue with the Products API

StripeKit 1.0.7 - 2019-08-03 23:36:34

Updated to use latest AsyncHTTPClient

StripeKit 1.0.6 - 2019-07-16 00:12:41

This release adopts the NIO pattern of retuning failed EventLoopFutures rather than having throwing functions. So instead of a do catch pattern you would opt for something like this instead

stripe.charges.create(amount: 2500,
                       currency: .usd,
		       description: "A server written in swift.",
                       source: "tok_visa")
 .flatMap { (charge) -> EventLoopFuture<Void> in
	  if charge.status == .succeeded {
	      print("New servers are on the way 🚀")
	  } else {
	      print("Sorry you have to use Node.js 🤢")
	  }
  }
  .flatMapError { error in
     print("Stripe error \(error.message)")
  }

More bug fixes - 2019-06-19 03:07:08

Fixed a type parsing issue.

Bug fixes - 2019-06-19 02:27:57

• Added correct headers on outgoing request. • Parse error response properly using top level error key.

Depend on Vapors fork of nio-http-client - 2019-06-14 23:47:55

StripeKit 1.0.0 🚀 - 2019-06-14 03:20:57