Skip to content

Instantly share code, notes, and snippets.

@jagdeepsingh
Last active September 15, 2017 11:23
Show Gist options
  • Save jagdeepsingh/57257a65b382b21f4e328f14d7b14569 to your computer and use it in GitHub Desktop.
Save jagdeepsingh/57257a65b382b21f4e328f14d7b14569 to your computer and use it in GitHub Desktop.
Stripe

Stripe Payment Gateway

Contents:

  1. Credit card encryption
  2. Create customers
  3. Create charges

Create an account on stripe.com and note the secret_key and publication_key. Stripe dashboard can be accessed here.

1 Credit card encryption

Docs: https://stripe.com/docs/stripe.js

Include https://js.stripe.com/v2/ in all your webpages.

Stripe.setPublishableKey('pk_test_9i6PDcXzPdFL0XDCb1bIHYAZ')

Deprecated approach to create a token for card information:

Stripe.card.createToken({
  name: 'Lance Melia',
  number: '4242424242424242',
  cvc: '123',
  exp_month: '11',
  exp_year: '2019'
}, stripeResponseHandler);

function stripeResponseHandler(status, response) {
  var $form = $('#payment-form');

  if (response.error) {
    $form.find('.payment-errors').text(response.error.message);
    $form.find('button').prop('disabled', false);
  } else {
    var token = response.id;
    $form.find('.cc-fields').remove();
    $form.append($('<input type="hidden" name="stripeToken" />').val(token));
    $form.get(0).submit();
  }
}

2 Create customers

Docs: https://stripe.com/docs/api/ruby

2.1 Install gems

# Gemfile
gem 'stripe', '~> 1.58.0'

Run bundle install. stripe-ruby is now installed.

2.2 Setup

# config/application.rb
require 'stripe'

If you will use one secret_key for all the requests, you can set it as:

# config/initializers/stripe.rb
Stripe.api_key = secret_key

But, if you have multiple secret_keys configured for different requests, you can pass the secret_key in each transaction request as a 2nd argument in the form of hash. We will see examples in following sections.

2.3 With token

customer = Stripe::Customer.create(source: TOKEN)
 => #<Stripe::Customer:0x3fd3ae2a1ba8 id=cus_BP4P5VV4FDeeGp> JSON: {
  "id": "cus_BP4P5VV4FDeeGp",
  "object": "customer",
  "account_balance": 0,
  "created": 1505468248,
  "currency": null,
  "default_source": "card_1B2GGIFdkxBnY304zU5OzQGe",
  "delinquent": false,
  "description": null,
  "discount": null,
  "email": null,
  "livemode": false,
  "metadata": {},
  "shipping": null,
  "sources": {"object":"list","data":[{"id":"card_1B2GGIFdkxBnY304zU5OzQGe","object":"card","address_city":null,"address_country":null,"address_line1":null,"address_line1_check":null,"address_line2":null,"address_state":null,"address_zip":null,"address_zip_check":null,"brand":"Visa","country":"US","customer":"cus_BP4P5VV4FDeeGp","cvc_check":"pass","dynamic_last4":null,"exp_month":8,"exp_year":2021,"fingerprint":"MSCfuhSAumSJRAyw","funding":"unknown","last4":"1111","metadata":{},"name":"Lisa Holder","tokenization_method":null}],"has_more":false,"total_count":1,"url":"/v1/customers/cus_BP4P5VV4FDeeGp/sources"},
  "subscriptions": {"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/customers/cus_BP4P5VV4FDeeGp/subscriptions"}
}

2.4 With card details

source = { object: 'card',
           name: 'Celia McClain',
           number: '4242424242424242',
           exp_year: 2017,
           exp_month: 11,
           cvc: '123' }
customer = Stripe::Customer.create(source: source)
=> #<Stripe::Customer:0x3ff5bc10b250 id=cus_Ao0zg7lih5PsZX> JSON: { "id": "cus_Ao0zg7lih5PsZX", "object": "customer", "account_balance": 0, "created": 1496921889, "currency": null, "default_source": "card_1ASOxnAz1CWwcBCU4RYCP28T", "delinquent": false, "description": null, "discount": null, "email": null, "livemode": false, "metadata": {}, "shipping": null, "sources": {"object":"list","data":[{"id":"card_1ASOxnAz1CWwcBCU4RYCP28T","object":"card","address_city":null,"address_country":null,"address_line1":null,"address_line1_check":null,"address_line2":null,"address_state":null,"address_zip":null,"address_zip_check":null,"brand":"Visa","country":"US","customer":"cus_Ao0zg7lih5PsZX","cvc_check":"pass","dynamic_last4":null,"exp_month":8,"exp_year":2017,"fingerprint":"qQL7mhQXZqvpA1Li","funding":"unknown","last4":"1111","metadata":{},"name":"Celia McClaine","tokenization_method":null}],"has_more":false,"total_count":1,"url":"/v1/customers/cus_Ao0zg7lih5PsZX/sources"}, "subscriptions": {"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/customers/cus_Ao0zg7lih5PsZX/subscriptions"} }

3 Create charges

Docs: https://stripe.com/docs/api#charges

3.1 Purchase

charge = Stripe::Charge.create(customer: customer.id,
                               currency: 'JPY',
                               amount: 1000)

You can also pass the credit card details instead of customer id.

credit_card = { object: 'card',
                number: '4242424242424242',
                exp_year: Time.now.year + 1,
                exp_month: 11,
                cvc: '123',
                name: 'Jagdeep Singh' }
charge = Stripe::Charge.create({ source: credit_card,
                                 currency: 'JPY',
                                 amount: 121843 }, api_key: secret_key)       # => #<Stripe::Charge:0x3fdb74fb30bc id=ch_19ieOgAz1CWwcBCUZbMBRMhh> JSON: { ... }
charge.status       # => "succeeded"
charge.id           # => "ch_19ieOgAz1CWwcBCUZbMBRMhh"
charge.captured     # => true
charge.source       # => #<Stripe::Card:0x3fdb74fcab54 id=card_19hzPMAz1CWwcBCUBkV0d2YP> JSON: { ... }
charge.outcome      # => #<Stripe::StripeObject:0x3fdb74fc78f0> JSON: { ... }

You can pass an additional idempotency_key in request params to make sure you don't charge a customer twice. It should be unique for each request.

charge = Stripe::Charge.create({ source: credit_card,
                                 currency: 'JPY',
                                 amount: 121843 },
                                api_key: secret_key,
                                idempotency_key: 'foobar')       # => #<Stripe::Charge:0x3fdb74fb30bc id=ch_19ieOgAz1CWwcBCUZbMBRMhh> JSON: { ... }

You can store references or any other useful information from your system on stripe with each charge.

charge = Stripe::Charge.create({ source: credit_card,
                                 currency: 'JPY',
                                 amount: 121843,
                                 metadata: { order_id: '12345' } },
                                api_key: secret_key)       # => #<Stripe::Charge:0x3fdb74fb30bc id=ch_19ieOgAz1CWwcBCUZbMBRMhh> JSON: { ... }
charge.metadata.order_id     # => "12345"

3.2 Authorize

charge = Stripe::Charge.create(customer: customer.id,
                               currency: 'JPY',
                               amount: 1000,
                               capture: false)
 => #<Stripe::Charge:0x3ff6040a5c00 id=ch_1B2GVOFdkxBnY304sXrMZypp> JSON: {
  "id": "ch_1B2GVOFdkxBnY304sXrMZypp",
  "object": "charge",
  "amount": 7093,
  "amount_refunded": 0,
  "application": null,
  "application_fee": null,
  "balance_transaction": null,
  "captured": false,
  "created": 1505469182,
  "currency": "jpy",
  "customer": "cus_BP4ewhYTfA3Qg6",
  "description": null,
  "destination": null,
  "dispute": null,
  "failure_code": null,
  "failure_message": null,
  "fraud_details": {},
  "invoice": null,
  "livemode": false,
  "metadata": {},
  "on_behalf_of": null,
  "order": null,
  "outcome": {"network_status":"approved_by_network","reason":null,"risk_level":"normal","seller_message":"Payment complete.","type":"authorized"},
  "paid": true,
  "receipt_email": null,
  "receipt_number": null,
  "refunded": false,
  "refunds": {"object":"list","data":[],"has_more":false,"total_count":0,"url":"/v1/charges/ch_1B2GVOFdkxBnY304sXrMZypp/refunds"},
  "review": null,
  "shipping": null,
  "source": {"id":"card_1B2GVBFdkxBnY304TwHGakl1","object":"card","address_city":null,"address_country":null,"address_line1":null,"address_line1_check":null,"address_line2":null,"address_state":null,"address_zip":null,"address_zip_check":null,"brand":"Visa","country":"US","customer":"cus_BP4ewhYTfA3Qg6","cvc_check":"pass","dynamic_last4":null,"exp_month":6,"exp_year":2020,"fingerprint":"MSCfuhSAumSJRAyw","funding":"unknown","last4":"1111","metadata":{},"name":"Lisa Holder","tokenization_method":null},
  "source_transfer": null,
  "statement_descriptor": null,
  "status": "succeeded",
  "transfer_group": null
}

3.3 Retrieve a charge

Stripe::Charge.retrieve(charge_id, api_key: secret_key)     # => #<Stripe::Charge:0x3fdb74e54be4 id=ch_19iNMMAz1CWwcBCU7kidzWfs> JSON: { ... }

3.4 Capture

You can fetch an uncaptured charge and call capture on it.

charge = Stripe::Charge.retrieve(charge.id, api_key: secret_key)
charge.capture               # => #<Stripe::Charge:0x3fdb76d81e18 id=ch_19ifhoAz1CWwcBCUm6K3i4O9> JSON: { ... }

If you want to capture a partial amount, the remaining amount will be refunded.

ch = charge.capture(amount: 50)   # => #<Stripe::Charge:0x3fdb76d81e18 id=ch_19ifhoAz1CWwcBCUm6K3i4O9> JSON: { ... }
ch.amount                         # => original amount
ch.amount_refunded                # => refunded amount

3.5 Void

You can create a Stripe::Refund on an authorized transaction to release the transaction.

refund = Stripe::Refund.create({ charge: charge.id }, api_key: secret_key)    # => #<Stripe::Refund:0x3feac253d6e8 id=re_19j1p5Az1CWwcBCUZoS1xnZc> JSON: { ... }
refund.object    # => "refund"
refund.status    # => "succeeded"

3.6 Refund

refund = Stripe::Refund.create({ charge: charge.id }, api_key: secret_key)    # => #<Stripe::Refund:0x3feac253d6e8 id=re_19j1p5Az1CWwcBCUZoS1xnZc> JSON: { ... }
refund.status    # => "succeeded"

For partial refunds, you can pass amount as an argument.

refund = Stripe::Refund.create({ charge: charge.id, amount: 500 }, api_key: secret_key)
refund.status    # => "succeeded"

You can also pass the reason for refund.

refund = Stripe::Refund.create({ charge: charge.id, reason: 'Out of stock' }, api_key: secret_key)
refund.status    # => "succeeded"

You can do multiple partial refunds until all the amount captured gets refunded.

3.7 Retrieve list of charges

Stripe::Charge.list({}, api_key: secret_key)       # => #<Stripe::ListObject:0x3fdb745e5d50> JSON: { ... }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment