SlideShare a Scribd company logo
Payments integration
Stripe & Taxamo
About me
Grzegorz Unijewski
Ruby on Rails Developer
grzegorz.unijewski@netguru.co
2/37
Agenda
3/37
● What is Stripe & Taxamo?
● Services integration based on my case
● Useful stuff
What is Stripe & Taxamo?
1.
4/37
Stripe
5/37
● Online payments platform
● Developer friendly documentation
● Paid per transaction
● Maintained Ruby client
● 1.4% + 20p for EU cards (2.9% for non-EU)
Stripe
6/37
Taxamo
7/37
● Global, real-time VAT & tax solution
● Paid monthly/annually
● €25/month or €19/month (up to €10k payments/month)
Taxamo
8/37
Case: subscriptions
2.
9/37
Subscriptions
10/37
● Purchase
● Annulment
● Renewal
Integration - preparing
11/37
# Gemfile
gem 'stripe'
# config/initializer/stripe.rb
Stripe.api_key = AppConfig.stripe.api_key # secret token
# Examples:
# list charges
Stripe::Charge.list()
# retrieve single charge
Stripe::Charge.retrieve(
"ch_123456789",
)
Integration - preparing
# Required data
:user # resource owner
:plan # subscription plan type
:tax_percent # tax rate
:stripe_token # stripe transaction key
:taxamo_token # taxamo transaction key
# Required column in User model
create_table "users", force: :cascade do |t|
[...]
t.string "stripe_cid"
end
12/37
Integration - preparing
13/37
URL:
https://api.taxamo.com/app/v1/webhooks/s
tripe?public_token=taxamo_public_key
Integration - preparing
14/37
For the payment form use Stripe.js or
ember-stripe-service.
Examples of good confirmation data:
● Credit card’s country & IP address
● Billing country & IP address
● Billing country & credit card’s country
Subscriptions
15/37
● Purchase
● Annulment
● Renewal
Subscription - purchase
16/37
# create_transaction
# delete_other_subscriptions if previous_subscriptions?
# grant_plan
Subscription - purchase
17/37
# create_transaction
## update_card if user.stripe_cid.present?
customer = Stripe::Customer.retrieve(user.stripe_cid)
customer.source = options[:stripe_token]
customer.save
## confirm_transaction
HTTParty.post(
"https://api.taxamo.com/api/v1/transactions/#{options[:taxamo_token]}/confirm",
{ query: { private_token: AppConfig.taxamo.private_token }
)
Subscription - purchase
18/37
# create_transaction
...
## create_subscription
Stripe::Subscription.create(
customer: user.stripe_cid,
plan: plan,
metadata: {
taxamo_transaction_key: options[:taxamo_token]
},
tax_percent: options[:tax_percent]
)
### if we don't have customer ID
customer_id = Stripe::Customer.create(source: options[:stripe_token], email: user.email).id
user.update(stripe_cid: customer_id)
Subscription - purchase
19/37
# create_transaction
# delete_other_subscriptions if previous_subscriptions?
# grant_plan
Subscription - purchase
20/37
# delete_other_subscriptions if previous_subscriptions?
subscriptions = Stripe::Customer.retrieve(user.stripe_cid).subscriptions
subscriptions.to_a.drop(1).present?
other_subscriptions_ids.map do |sub_id|
Stripe::Subscription.retrieve(sub_id).delete
end
# grant_plan
account_plan = { plan: plan, currency: currency }
SubscriptionServices::SubscriptionGrantor.new(user: user, new_plan: account_plan).call
Subscriptions
21/37
● Purchase
● Annulment
● Renewal
Subscription - annulment
22/37
def cancel_subscription
stripe_subscription = Stripe::Subscription.retrieve(subscription_id)
stripe_subscription.delete(at_period_end: true)
user.active_subscription.update(is_cancelled: true)
end
def subscription_id
customer = Stripe::Customer.retrieve(user.stripe_cid)
customer.subscriptions.first.id
end
Subscriptions
23/37
● Purchase
● Annulment
● Renewal
Subscription - renewal
24/37
● Add a new webhook with URL:
https://myapp.com/api/v1/subscriptions/events?access_token=your_token
for customer.subscription.updated event
● Handle it in the endpoint
● Don’t forget about authorization
Subscription - renewal
25/37
def call
user.subscriptions.last.update(end_date: end_date)
end
private
def json_object
@json_object ||= event_json['data']['object']
end
def user
customer_id = json_object['customer']
User.find_by!(stripe_cid: customer_id)
end
def end_date
date = json_object['current_period_end']
Time.at(date)
end
Useful stuff
3.
26/37
stripe_event
27/37
gem 'stripe_event'
# config/routes.rb
mount StripeEvent::Engine, at: '/my-chosen-path' # provide a custom path
# config/initializers/stripe.rb
Stripe.api_key = ENV['STRIPE_SECRET_KEY'] # e.g. sk_live_1234
StripeEvent.configure do |events|
events.subscribe 'charge.failed' do |event|
# Define subscriber behavior based on the event object
event.class #=> Stripe::Event
event.type #=> "charge.failed"
event.data.object #=> #<Stripe::Charge:0x3fcb34c115f8>
end
events.all do |event|
events.all BillingEventLogger.new(Rails.logger)
events.subscribe 'customer.created', CustomerCreated.new
end
end
stripe-ruby-mock
28/37
gem 'stripe-ruby-mock', '~> 2.3.1', require: 'stripe_mock'
require 'stripe_mock'
describe MyApp do
let(:stripe_helper) { StripeMock.create_test_helper }
before { StripeMock.start }
after { StripeMock.stop }
it "creates a stripe customer" do
# This doesn't touch stripe's servers nor the internet!
# Specify :source in place of :card (with same value) to return customer with source data
customer = Stripe::Customer.create({
email: 'johnny@appleseed.com',
card: stripe_helper.generate_card_token
})
expect(customer.email).to eq('johnny@appleseed.com')
end
end
stripe-ruby-mock
29/37
stripe_helper.create_plan(my_plan_params)
stripe_helper.delete_plan(my_plan_params)
stripe_helper.generate_card_token(my_card_params)
let(:customer) do
Stripe::Util.convert_to_stripe_object(
{
object: 'customer',
source: 'source',
subscriptions: subscriptions_array
}, {}
)
end
let(:stripe_subscription) do
Stripe::Util.convert_to_stripe_object({ object: 'subscription', id: '1' }, {})
end
Links
30/37
● Stripe API reference: https://stripe.com/docs/api/ruby
● Taxamo API reference: https://www.taxamo.com/apidocs/
● Stripe-ruby: https://github.com/stripe/stripe-ruby
● Stripe-ruby-mock: https://github.com/rebelidealist/stripe-ruby-mock
● Stripe_event: https://github.com/integrallis/stripe_event
● Taxamo-ruby: https://github.com/taxamo/taxamo-ruby
● Stripe JS reference: https://stripe.com/docs/stripe.js
● Ember-stripe-service: https://github.com/code-corps/ember-stripe-service
Q&A
31/37
Ruby on Rails Development Team
32/37
● ~ 80 developers including
○ ~ 20 seniors
○ ~ 10 team leaders
Ruby on Rails Developer must-haves:
33/37
● Have a hands-on knowledge of Ruby on Rails, HAML/SASS
● Have knowledge of at least one of JavaScript frameworks
(AngularJS/Ember.js, React, jQuery)
● You know how to deal efficiently with databases and various queries
● You have very good command of written and spoken English (minimum
B2)
● You have experience in direct communication with clients
Juniors are more than welcome! You just need to:
34/37
● Have some basic knowledge in Ruby and Ruby on Rails
● Have at least one Rails app on your GitHub account
● Be fluent in English - at least B2 level, spoken and written
● Be ready to work at least 35 hours/week, from Monday till
Friday
How to join our awesome team?
35/37
● Step one - check our career path and see what level you are
netguru.co/career/paths
● Step two - apply for the proper position - netguru.co/career
● Step three - take part in our recruitment process - solve the
task and join us for the remote interview and pair programming
● Step four - welcome onboard!
36/37
Any questions regarding recruitment process?
Drop us a line at jobs@netguru.co
Don’t hesitate and join our team!
Thanks!
37/37

More Related Content

PPTX
Location Based Services
PPTX
6Tisch telecom_bretagne_2016
PPT
GESTURE RECOGNITION TECHNOLOGY
DOC
online book sale srs Apeksha
PPT
Android ppt
PDF
Document Presentment by OpenText
PPTX
Different types of mobile apps
PDF
Mastering SAP Monitoring - Workload Monitoring
Location Based Services
6Tisch telecom_bretagne_2016
GESTURE RECOGNITION TECHNOLOGY
online book sale srs Apeksha
Android ppt
Document Presentment by OpenText
Different types of mobile apps
Mastering SAP Monitoring - Workload Monitoring

What's hot (13)

PPTX
Mobile application development ppt
PPTX
PPTX
Mobile Application Development: Hybrid, Native and Mobile Web Apps
PPTX
Technology in 2024
PDF
IoT and WoT (Internet of Things and Web of Things)
PPTX
Android Library Management System
PPTX
Geocoding for beginners
PDF
Mobile Application Design & Development
ODP
Hybrid application development
PPTX
PWA - Progressive Web App
PPT
Artificial Passenger
PDF
Internet Of things
PPTX
Hybrid Mobile App
Mobile application development ppt
Mobile Application Development: Hybrid, Native and Mobile Web Apps
Technology in 2024
IoT and WoT (Internet of Things and Web of Things)
Android Library Management System
Geocoding for beginners
Mobile Application Design & Development
Hybrid application development
PWA - Progressive Web App
Artificial Passenger
Internet Of things
Hybrid Mobile App
Ad

Viewers also liked (8)

PDF
Rozwijanie firmy web developerskiej - Kuba Filipowski, Wiktor Schmidt, Netguru
PDF
301 Adam Zygadlewicz
PPTX
Strategia w Social Media w 6 krokach
PDF
Why Would A Programmer Fall In Love With SPA?
PDF
KISS Augmented Reality
PDF
Czy Project Manger Musi Być Osobą Techniczną?
PPT
Blogi w firmie
PDF
Hidden Gems in Swift
Rozwijanie firmy web developerskiej - Kuba Filipowski, Wiktor Schmidt, Netguru
301 Adam Zygadlewicz
Strategia w Social Media w 6 krokach
Why Would A Programmer Fall In Love With SPA?
KISS Augmented Reality
Czy Project Manger Musi Być Osobą Techniczną?
Blogi w firmie
Hidden Gems in Swift
Ad

Similar to Payments integration: Stripe & Taxamo (20)

PDF
Moore Advanced Calculations in Calc Manager OW 20151015
PDF
Using Graphs for Feature Engineering_ Graph Reduce-2.pdf
PDF
Moving away from legacy code with BDD
PDF
Streamlining Feature Engineering Pipelines with Open Source
PDF
DRUPAL AUDITS MADE FASTR
PDF
A Technical Introduction to RTBkit
PPTX
Behavior-driven Development and Lambdaj
PDF
From class to architecture
PDF
Towards cross-platfrom application development
PPT
BPCS Infor ERP LX Implementation Evaluation Q4 2007
PDF
On component interface
PDF
Biconomy - ETHglobal workshop
PPTX
Presentation 2315006 done
PDF
Graphdo overview
PDF
eBPF/XDP
PDF
Industrail training report on website design and development
PDF
"Impact of front-end architecture on development cost", Viktor Turskyi
ODP
Hybrid rule engines (rulesfest 2010)
PDF
Agados Function & Feature
PDF
Turbogears2 tutorial to create mvc app
Moore Advanced Calculations in Calc Manager OW 20151015
Using Graphs for Feature Engineering_ Graph Reduce-2.pdf
Moving away from legacy code with BDD
Streamlining Feature Engineering Pipelines with Open Source
DRUPAL AUDITS MADE FASTR
A Technical Introduction to RTBkit
Behavior-driven Development and Lambdaj
From class to architecture
Towards cross-platfrom application development
BPCS Infor ERP LX Implementation Evaluation Q4 2007
On component interface
Biconomy - ETHglobal workshop
Presentation 2315006 done
Graphdo overview
eBPF/XDP
Industrail training report on website design and development
"Impact of front-end architecture on development cost", Viktor Turskyi
Hybrid rule engines (rulesfest 2010)
Agados Function & Feature
Turbogears2 tutorial to create mvc app

More from Netguru (20)

PDF
Defining DSL (Domain Specific Language) using Ruby
PDF
How To Build Great Relationships With Your Clients
PDF
Agile Retrospectives
PDF
Ruby Rails Overview
PDF
From Birds To Bugs: Testowanie Z Pasją
PDF
Communication With Clients Throughout The Project
PDF
Everyday Rails
PDF
Estimation myths debunked
PDF
Programming Paradigms Which One Is The Best?
PDF
Z 50 do 100 w ciągu roku Jak rekrutować w IT?
PDF
Paradygmaty Programowania: Czy Istnieje Najlepszy?
PDF
CSS architecture: How To Write Clean & Scalable Code
PDF
Ruby On Rails Intro
PDF
Perfect Project Read Me (in a few steps)
PDF
The Git Basics
PDF
From nil to guru: intro to Ruby on Rails
PDF
Working With Teams Across The Borders
PDF
Front-End Dev Tools
PDF
OOScss Architecture For Rails Apps
KEY
Coffeescript presentation DublinJS
Defining DSL (Domain Specific Language) using Ruby
How To Build Great Relationships With Your Clients
Agile Retrospectives
Ruby Rails Overview
From Birds To Bugs: Testowanie Z Pasją
Communication With Clients Throughout The Project
Everyday Rails
Estimation myths debunked
Programming Paradigms Which One Is The Best?
Z 50 do 100 w ciągu roku Jak rekrutować w IT?
Paradygmaty Programowania: Czy Istnieje Najlepszy?
CSS architecture: How To Write Clean & Scalable Code
Ruby On Rails Intro
Perfect Project Read Me (in a few steps)
The Git Basics
From nil to guru: intro to Ruby on Rails
Working With Teams Across The Borders
Front-End Dev Tools
OOScss Architecture For Rails Apps
Coffeescript presentation DublinJS

Recently uploaded (20)

PDF
System and Network Administration Chapter 2
PPTX
history of c programming in notes for students .pptx
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Digital Strategies for Manufacturing Companies
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
Transform Your Business with a Software ERP System
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
L1 - Introduction to python Backend.pptx
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
medical staffing services at VALiNTRY
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Understanding Forklifts - TECH EHS Solution
PPTX
Online Work Permit System for Fast Permit Processing
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
System and Network Administration Chapter 2
history of c programming in notes for students .pptx
How Creative Agencies Leverage Project Management Software.pdf
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
VVF-Customer-Presentation2025-Ver1.9.pptx
Digital Strategies for Manufacturing Companies
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Transform Your Business with a Software ERP System
How to Choose the Right IT Partner for Your Business in Malaysia
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
L1 - Introduction to python Backend.pptx
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Design an Analysis of Algorithms I-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
Adobe Illustrator 28.6 Crack My Vision of Vector Design
medical staffing services at VALiNTRY
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Understanding Forklifts - TECH EHS Solution
Online Work Permit System for Fast Permit Processing
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf

Payments integration: Stripe & Taxamo

  • 2. About me Grzegorz Unijewski Ruby on Rails Developer grzegorz.unijewski@netguru.co 2/37
  • 3. Agenda 3/37 ● What is Stripe & Taxamo? ● Services integration based on my case ● Useful stuff
  • 4. What is Stripe & Taxamo? 1. 4/37
  • 5. Stripe 5/37 ● Online payments platform ● Developer friendly documentation ● Paid per transaction ● Maintained Ruby client ● 1.4% + 20p for EU cards (2.9% for non-EU)
  • 7. Taxamo 7/37 ● Global, real-time VAT & tax solution ● Paid monthly/annually ● €25/month or €19/month (up to €10k payments/month)
  • 11. Integration - preparing 11/37 # Gemfile gem 'stripe' # config/initializer/stripe.rb Stripe.api_key = AppConfig.stripe.api_key # secret token # Examples: # list charges Stripe::Charge.list() # retrieve single charge Stripe::Charge.retrieve( "ch_123456789", )
  • 12. Integration - preparing # Required data :user # resource owner :plan # subscription plan type :tax_percent # tax rate :stripe_token # stripe transaction key :taxamo_token # taxamo transaction key # Required column in User model create_table "users", force: :cascade do |t| [...] t.string "stripe_cid" end 12/37
  • 14. Integration - preparing 14/37 For the payment form use Stripe.js or ember-stripe-service. Examples of good confirmation data: ● Credit card’s country & IP address ● Billing country & IP address ● Billing country & credit card’s country
  • 16. Subscription - purchase 16/37 # create_transaction # delete_other_subscriptions if previous_subscriptions? # grant_plan
  • 17. Subscription - purchase 17/37 # create_transaction ## update_card if user.stripe_cid.present? customer = Stripe::Customer.retrieve(user.stripe_cid) customer.source = options[:stripe_token] customer.save ## confirm_transaction HTTParty.post( "https://api.taxamo.com/api/v1/transactions/#{options[:taxamo_token]}/confirm", { query: { private_token: AppConfig.taxamo.private_token } )
  • 18. Subscription - purchase 18/37 # create_transaction ... ## create_subscription Stripe::Subscription.create( customer: user.stripe_cid, plan: plan, metadata: { taxamo_transaction_key: options[:taxamo_token] }, tax_percent: options[:tax_percent] ) ### if we don't have customer ID customer_id = Stripe::Customer.create(source: options[:stripe_token], email: user.email).id user.update(stripe_cid: customer_id)
  • 19. Subscription - purchase 19/37 # create_transaction # delete_other_subscriptions if previous_subscriptions? # grant_plan
  • 20. Subscription - purchase 20/37 # delete_other_subscriptions if previous_subscriptions? subscriptions = Stripe::Customer.retrieve(user.stripe_cid).subscriptions subscriptions.to_a.drop(1).present? other_subscriptions_ids.map do |sub_id| Stripe::Subscription.retrieve(sub_id).delete end # grant_plan account_plan = { plan: plan, currency: currency } SubscriptionServices::SubscriptionGrantor.new(user: user, new_plan: account_plan).call
  • 22. Subscription - annulment 22/37 def cancel_subscription stripe_subscription = Stripe::Subscription.retrieve(subscription_id) stripe_subscription.delete(at_period_end: true) user.active_subscription.update(is_cancelled: true) end def subscription_id customer = Stripe::Customer.retrieve(user.stripe_cid) customer.subscriptions.first.id end
  • 24. Subscription - renewal 24/37 ● Add a new webhook with URL: https://myapp.com/api/v1/subscriptions/events?access_token=your_token for customer.subscription.updated event ● Handle it in the endpoint ● Don’t forget about authorization
  • 25. Subscription - renewal 25/37 def call user.subscriptions.last.update(end_date: end_date) end private def json_object @json_object ||= event_json['data']['object'] end def user customer_id = json_object['customer'] User.find_by!(stripe_cid: customer_id) end def end_date date = json_object['current_period_end'] Time.at(date) end
  • 27. stripe_event 27/37 gem 'stripe_event' # config/routes.rb mount StripeEvent::Engine, at: '/my-chosen-path' # provide a custom path # config/initializers/stripe.rb Stripe.api_key = ENV['STRIPE_SECRET_KEY'] # e.g. sk_live_1234 StripeEvent.configure do |events| events.subscribe 'charge.failed' do |event| # Define subscriber behavior based on the event object event.class #=> Stripe::Event event.type #=> "charge.failed" event.data.object #=> #<Stripe::Charge:0x3fcb34c115f8> end events.all do |event| events.all BillingEventLogger.new(Rails.logger) events.subscribe 'customer.created', CustomerCreated.new end end
  • 28. stripe-ruby-mock 28/37 gem 'stripe-ruby-mock', '~> 2.3.1', require: 'stripe_mock' require 'stripe_mock' describe MyApp do let(:stripe_helper) { StripeMock.create_test_helper } before { StripeMock.start } after { StripeMock.stop } it "creates a stripe customer" do # This doesn't touch stripe's servers nor the internet! # Specify :source in place of :card (with same value) to return customer with source data customer = Stripe::Customer.create({ email: 'johnny@appleseed.com', card: stripe_helper.generate_card_token }) expect(customer.email).to eq('johnny@appleseed.com') end end
  • 29. stripe-ruby-mock 29/37 stripe_helper.create_plan(my_plan_params) stripe_helper.delete_plan(my_plan_params) stripe_helper.generate_card_token(my_card_params) let(:customer) do Stripe::Util.convert_to_stripe_object( { object: 'customer', source: 'source', subscriptions: subscriptions_array }, {} ) end let(:stripe_subscription) do Stripe::Util.convert_to_stripe_object({ object: 'subscription', id: '1' }, {}) end
  • 30. Links 30/37 ● Stripe API reference: https://stripe.com/docs/api/ruby ● Taxamo API reference: https://www.taxamo.com/apidocs/ ● Stripe-ruby: https://github.com/stripe/stripe-ruby ● Stripe-ruby-mock: https://github.com/rebelidealist/stripe-ruby-mock ● Stripe_event: https://github.com/integrallis/stripe_event ● Taxamo-ruby: https://github.com/taxamo/taxamo-ruby ● Stripe JS reference: https://stripe.com/docs/stripe.js ● Ember-stripe-service: https://github.com/code-corps/ember-stripe-service
  • 32. Ruby on Rails Development Team 32/37 ● ~ 80 developers including ○ ~ 20 seniors ○ ~ 10 team leaders
  • 33. Ruby on Rails Developer must-haves: 33/37 ● Have a hands-on knowledge of Ruby on Rails, HAML/SASS ● Have knowledge of at least one of JavaScript frameworks (AngularJS/Ember.js, React, jQuery) ● You know how to deal efficiently with databases and various queries ● You have very good command of written and spoken English (minimum B2) ● You have experience in direct communication with clients
  • 34. Juniors are more than welcome! You just need to: 34/37 ● Have some basic knowledge in Ruby and Ruby on Rails ● Have at least one Rails app on your GitHub account ● Be fluent in English - at least B2 level, spoken and written ● Be ready to work at least 35 hours/week, from Monday till Friday
  • 35. How to join our awesome team? 35/37 ● Step one - check our career path and see what level you are netguru.co/career/paths ● Step two - apply for the proper position - netguru.co/career ● Step three - take part in our recruitment process - solve the task and join us for the remote interview and pair programming ● Step four - welcome onboard!
  • 36. 36/37 Any questions regarding recruitment process? Drop us a line at jobs@netguru.co Don’t hesitate and join our team!