All Projects â†’ vapor-community â†’ Stripe Kit

vapor-community / Stripe Kit

Licence: mit

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Stripe Kit

nuxt-stripejs
💳 NuxtJS module for Stripe.js which loads only when required and w/ retry mechanism
Stars: ✭ 17 (-66%)
Mutual labels:  stripe, stripe-api
stripe-scala
Scala library for the Stripe API
Stars: ✭ 33 (-34%)
Mutual labels:  stripe, stripe-api
stripe-course
Stripe Payments In Practice - Build your own online ecommerce store and subscription membership website
Stars: ✭ 31 (-38%)
Mutual labels:  stripe, stripe-api
stripe
Stripe integration with Magento 2
Stars: ✭ 58 (+16%)
Mutual labels:  stripe, stripe-api
Vue Stripe Elements
A Vue 2 component collection for StripeElements
Stars: ✭ 498 (+896%)
Mutual labels:  stripe-api, stripe
MERN-Ecommerce
An E-commerce app built using MERN stack. It has 4 social login options and implements email verification as well. Stripe and Paypal payment gateways are implemented.
Stars: ✭ 50 (+0%)
Mutual labels:  stripe, stripe-api
Stripity stripe
An Elixir Library for Stripe
Stars: ✭ 597 (+1094%)
Mutual labels:  stripe-api, stripe
React Express Stripe
💰 Minimal Boilerplate for Stripe used in React and Express. Charge payments from your customers with this project.
Stars: ✭ 209 (+318%)
Mutual labels:  stripe-api, stripe
Stripe Connect Rocketrides
Sample on-demand platform built on Stripe: Connect onboarding for pilots, iOS app for passengers to request rides.
Stars: ✭ 426 (+752%)
Mutual labels:  stripe-api, stripe
Stripe Webhook Monitor
Stripe Webhook Monitor provides a real-time feed and graph of Stripe events received via webhooks. 📈✨
Stars: ✭ 356 (+612%)
Mutual labels:  stripe-api, stripe
pinax-stripe-light
a payments Django app for Stripe
Stars: ✭ 670 (+1240%)
Mutual labels:  stripe, stripe-api
Stripe Rs
Moved to https://github.com/wyyerd/stripe-rs.
Stars: ✭ 16 (-68%)
Mutual labels:  stripe-api, stripe
stripe-graphql
[WIP] 🚧🚧🚧 😎 Community-driven Stripe GraphQL API with superpowers.
Stars: ✭ 53 (+6%)
Mutual labels:  stripe, stripe-api
Pinax Stripe
a payments Django app for Stripe
Stars: ✭ 650 (+1200%)
Mutual labels:  stripe-api, stripe
TradeByte
💸 TradeByte - Stocks Trading Simulation WebApp
Stars: ✭ 30 (-40%)
Mutual labels:  stripe, stripe-api
procesa-pagos-con-laravel
Código fuente resultado del curso "Procesa pagos con Laravel y las mejores plataformas de pagos"
Stars: ✭ 38 (-24%)
Mutual labels:  stripe, stripe-api
Stripe
💰 Stripe API
Stars: ✭ 150 (+200%)
Mutual labels:  stripe-api, stripe
Stripe
Stripe library for Vapor
Stars: ✭ 151 (+202%)
Mutual labels:  stripe-api, stripe
Nest-Js-Boiler-Plate
Nest Js Boilerplate with JWT authentication, CRUD functions and payment gateways.
Stars: ✭ 14 (-72%)
Mutual labels:  stripe, stripe-api
Stripy
Micro wrapper for Stripe's REST API.
Stars: ✭ 49 (-2%)
Mutual labels:  stripe-api, stripe

StripeKit

Test

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

Version support

You can check the CHANGELOG to see which version of StripeKit meets your needs.

Installation

To start using StripeKit, in your Package.swift, add the following

.package(url: "https://github.com/vapor-community/stripe-kit.git", from: "9.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 🤢")
                          }
            }

Expandable objects

StripeKit supports expandable objects via 2 property wrappers:

@Expandable and @DynamicExpandable

All API routes that can return expanded objects have an extra parameter expand: [String]? that allows specifying which objects to expand.

Usage with @Expandable:

  1. Expanding a single field.
// Expanding a customer from creating a `PaymentIntent`.
stripeclient.paymentIntents.create(amount: 2500, currency: .usd, expand: ["customer"])
.flatMap { paymentIntent in
// Accessing the expanded `StripeCustomer` object   
 paymentIntent.$customer.email
...
}
  1. Expanding multiple fields.
// Expanding a customer and payment method from creating a `PaymentIntent`.
stripeclient.paymentIntents.create(amount: 2500, currency: .usd, expand: ["customer", "paymentMethod"])
.flatMap { paymentIntent in
// Accessing the expanded `StripeCustomer` object   
 paymentIntent.$customer?.email // "[email protected]"
// Accessing the expanded `StripePaymentMethod` object
 paymentIntent.$paymentMethod?.card?.last4 // "1234"
 ...
}
  1. Expanding nested fields.
// Expanding a payment method and its nested customer from creating a `PaymentIntent`.
stripeclient.paymentIntents.create(amount: 2500, currency: .usd, expand: ["paymentMethod.customer"])
.flatMap { paymentIntent in
// Accessing the expanded `StripePaymentMethod` object
 paymentIntent.$paymentMethod?.card?.last4 // "1234"
// Accessing the nested expanded `StripeCustomer` object   
 paymentIntent.$paymentMethod?.$customer?.email // "[email protected]"
 ...
}
  1. Usage with list all.

Note: For list operations expanded fields must start with data

// Expanding a customer from listing all `PaymentIntent`s.
stripeclient.paymentIntents.listAll(filter: ["expand": ["data.customer"...]])
.flatMap { list in
 // Accessing the first `StripePaymentIntent`'s expanded `StripeCustomer` property
  list.data?.first?.$customer?.email // "[email protected]"
}

Usage with @DynamicExpandable:

Some objects in stripe can be expanded into different objects. For example:

A StripeApplicationFee has an originatingTransaction property that can be expanded into either a charge or a transfer.

When expanding it you can specify which object you expect by doing the following:

stripeclient.applicationFees.retrieve(fee: "fee_1234", expand: ["originatingTransaction"])
.flatMap { applicationfee in 
    // Access the originatingTransaction as a StripeCharge
    applicationfee.$originatingTransaction(as: StripeCharge.self)?.amount // 2500
    ...
    // Access the originatingTransaction as a StripeTransfer
    applicationfee.$originatingTransaction(as: StripeTransfer.self)?.destination // acc_1234
}

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: "[email protected]",
				  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`.
~~~swift
 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)")
  }

Webhooks

The webhooks API is available to use in a typesafe way to pull out entities. Here's an example of listening for the payment intent webhook.

func handleStripeWebhooks(req: Request) throws -> EventLoopFuture<HTTPResponse> {

    let signature = req.headers["Stripe-Signature"]

    try StripeClient.verifySignature(payload: req.body, header: signature, secret: "whsec_1234") 
    // Stripe dates come back from the Stripe API as epoch and the StripeModels convert these into swift `Date` types.
    // Use a date and key decoding strategy to successfully parse out the `created` property and snake case strpe properties. 
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .secondsSince1970
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    
    let event = try decoder.decode(StripeEvent.self, from: req.bodyData)
    
    switch (event.type, event.data?.object) {
    case (.paymentIntentSucceeded, .paymentIntent(let paymentIntent)):
        print("Payment capture method: \(paymentIntent.captureMethod?.rawValue)")
        return eventLoop.makeSucceededFuture(HTTPResponse(status: .ok))
        
    default: return eventLoop.makeSucceededFuture(HTTPResponse(status: .ok))
    }
}

Vapor Integration

See the Vapor helper library to use StripeKit with Vapor.

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] SetupAttempts
  • [x] Payouts
  • [x] Prices
  • [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 Portal
  • [x] Customer Tax IDs
  • [x] Discounts
  • [x] Invoices
  • [x] Invoice Items
  • [x] Plans
  • [x] Promotion Codes
  • [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
  • [x] Signature Verification

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! 😀

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].