Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

CHADDA Chakib
CHADDA Chakib

Posted on

     

Stripe Strong Customer Authentication & Rails

You maybe heard about the migration of theStripe CB payment toSCA Strong Customer Authentication
All payment from the European countries are concerned.

For more information,The stripe sca doc

The customer experience through the SCA

For your customer, after he puts the Credit card number, the bank can ask for a confirmation bySMS or a push notification in bank app in his smartphone.

Stripe now handle this and for better experience, they need to redirect the user to hosted page by stripe and will handle all the complexity.
When succeed or failed, the user is redirected to your webapp.

This is the flow that explain how this works

Alt Text

The main steps handled by the rails app are two

  1. The preparation of the checkout session [generation of the key]
  2. The validation of the payment [Verify the key]

1. The session preparation

This will prepareStripe session for the checkout of the product and the redirection when the payment succeed or not.

So we will prepare

  1. The name of the product
  2. The price
  3. The redirection when succeed or not
secret=gen_secret(@product)Stripe::Checkout::Session.create({payment_method_types:['card'],line_items:[{name:@product.name,description:@product.description,amount:@product.price,currency:'eur',quantity:1,}],success_url:confirm_product_payment_url(@product,secret:secret),cancel_url:cancel_product_payment_url(@product)})
Enter fullscreen modeExit fullscreen mode

The interesting part here is thegen_secret

We need to generate thissecret to be able to be sure and verify that the payment atStripe succeed and the callback is not faked

We can generate this key like that in rails.
Thanks to rails to provide everything inside the framework and no need to add foreign dependency.

defgen_secret(product)key=Rails.application.secrets.secret_key_base@crypt=ActiveSupport::MessageEncryptor.new(key[0,32],cipher:'aes-256-gcm')@crypt.encrypt_and_sign(product.token)end
Enter fullscreen modeExit fullscreen mode

As I explained in the previousUML flow, the callbacks containing this secret will be stored atstripe using a secure connection from your server.

The Payment process

The payment process is classic, the customer will enter his credit card numbers and may use a strong authentication if needed (SMS code verification, push notification ... ect)

When the payment succeed

At this step, the stripe servers will send to the browser the redirection to the right callback url.
This callback is containing oursecret generated before.
Time to validation !

2. The Validation process

Now, our rails app should verify this callback, in ruby it's easy
For this example I will use a simple verification.

I will only verify if decrypted token is the real token of the product.

# in the product controllerdefconfirm@product=current_productifPaymentService.new(product:@product).confirm(secret:params[:secret])flash[:success]="Payment succeed"elseflash[:error]="Oups Error !"endredirect_toproduct_url(@product)end# inside the PaymentService...defconfirm(secret)if@crypt.decrypt_and_verify(secret)==@product.token# handle the success of the payment# notifications, emails ...ectreturntrueelsereturnfalseendend
Enter fullscreen modeExit fullscreen mode

The Front-end

Thanks toStripe the front-end is easy !
So, when the customer want to pay a product, he will click on thepayment button.

Alt Text

This will call ourrails app to prepare the session, get back the redirection and follow it.

<%= button_to product_pay_path(@product),     method: :post,     id: "pay_sca",     data: { disable_with: '<i class="fa fa-spinner fa-spin"></i>'.html_safe },     class: "btn btn-success btn-lg btn-block",     remote: true do  %>      <i></i>Payer<% end%>
Enter fullscreen modeExit fullscreen mode

man that's concise !, this will call our controller by ajax, show a cool animation when waiting for the response of the server and finaly follow the redirection toStripe.

# controllerdefcreate@company_travel=current_travel.company@session_id=PaymentService.new(product:current_product).create_session.idend
Enter fullscreen modeExit fullscreen mode

As you have maybe notice, we are using a CRUD resource, when a customer need to pay wecreate acharging resource.

The view part is simple also

# views/.../create.js.erbconststripe=Stripe('<%= Rails.application.secrets.stripe_public_key %>');stripe.redirectToCheckout({//WeputhereoursessionIDsessionId:'<%= @session_id %>'}).then((result)=>{//If`redirectToCheckout`failsduetoabrowserornetwork//error,displaythelocalizederrormessagetoyourcustomer//using`result.error.message`.});
Enter fullscreen modeExit fullscreen mode

Easy yay !

I think now we are good to go.

Testing this will be in an other blog post withsystem tests.

As a gift, The complete service can look like this

classPaymentServiceincludeRails.application.routes.url_helpersdefinitialize(product:)@product=productkey=Rails.application.secrets.secret_key_base@cryptor=ActiveSupport::MessageEncryptor.new(key[0,32],cipher:'aes-256-gcm')enddefcreate_sessionsecret=gen_secretStripe::Checkout::Session.create({payment_method_types:['card'],line_items:[{name:@product.namedescription:@product.description,amount:@product.price,currency:'eur',quantity:1,}],success_url:confirm_product_payment_url(@product,secret:secret),cancel_url:cancel_product_payment_url(@product)})enddefconfirm(secret)if@cryptor.decrypt_and_verify(secret)==@product.token# handle a succeed payment# send notifications, invoices ... ectreturntrueelsereturnfalseendendprivatedefgen_secret@cryptor.encrypt_and_sign(@product.token)endend
Enter fullscreen modeExit fullscreen mode

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Slapping the keyboard with love and passion until something valuable to people happen !
  • Location
    Paris
  • Education
    BS CS
  • Work
    founder at toncarton
  • Joined

More fromCHADDA Chakib

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp