mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
collect card details on the client & create a paymentIntent on the server
This commit is contained in:
parent
a0961314a4
commit
12447698f8
@ -1,10 +1,10 @@
|
|||||||
/* global Stripe */
|
/* global Stripe */
|
||||||
|
|
||||||
Application.Directives.directive('stripeForm', ['$window',
|
Application.Directives.directive('stripeForm', ['Payment',
|
||||||
function ($window) {
|
function (Payment) {
|
||||||
return ({
|
return ({
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: ($scope, element, attributes) => {
|
link: function($scope, element, attributes) {
|
||||||
const stripe = Stripe('<%= Rails.application.secrets.stripe_publishable_key %>');
|
const stripe = Stripe('<%= Rails.application.secrets.stripe_publishable_key %>');
|
||||||
const elements = stripe.elements();
|
const elements = stripe.elements();
|
||||||
|
|
||||||
@ -40,29 +40,24 @@ Application.Directives.directive('stripeForm', ['$window',
|
|||||||
const cardElement = form.find('#card-element');
|
const cardElement = form.find('#card-element');
|
||||||
card.mount(cardElement[0]);
|
card.mount(cardElement[0]);
|
||||||
|
|
||||||
form.bind('submit', async () => {
|
form.bind('submit', function() {
|
||||||
const button = form.find('button');
|
const button = form.find('button');
|
||||||
button.prop('disabled', true);
|
button.prop('disabled', true);
|
||||||
|
|
||||||
// TODO https://stripe.com/docs/payments/payment-intents/web-manual
|
// TODO https://stripe.com/docs/payments/payment-intents/web-manual
|
||||||
const { paymentMethod, error } = await stripe.createPaymentMethod('card', cardElement);
|
stripe.createPaymentMethod('card', card).then(function({ paymentMethod, error }) {
|
||||||
if (error) {
|
if (error) {
|
||||||
// Show error in payment form
|
// Show error in payment form
|
||||||
} else {
|
} else {
|
||||||
// Send paymentMethod.id to your server (see Step 2)
|
// Send paymentMethod.id to your server (see Step 2)
|
||||||
const response = await fetch('/ajax/confirm_payment', {
|
Payment.confirm({ payment_method_id: paymentMethod.id }).then(function (response) {
|
||||||
method: 'POST',
|
// Handle server response (see Step 3)
|
||||||
headers: { 'Content-Type': 'application/json' },
|
$scope.$apply(function () {
|
||||||
body: JSON.stringify({ payment_method_id: paymentMethod.id })
|
$scope[form].apply($scope, response);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
const json = await response.json();
|
}
|
||||||
|
});
|
||||||
// Handle server response (see Step 3)
|
|
||||||
$scope.$apply(function () {
|
|
||||||
$scope[form].apply($scope, json);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
13
app/assets/javascripts/services/payment.js
Normal file
13
app/assets/javascripts/services/payment.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
Application.Services.factory('Payment', ['$resource', function ($resource) {
|
||||||
|
return $resource('/api/payments',
|
||||||
|
{}, {
|
||||||
|
confirm: {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/api/payments/confirm_payment',
|
||||||
|
isArray: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}]);
|
@ -4,7 +4,6 @@
|
|||||||
class API::PaymentsController < API::ApiController
|
class API::PaymentsController < API::ApiController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
|
|
||||||
# TODO https://stripe.com/docs/payments/payment-intents/web-manual
|
|
||||||
def confirm_payment
|
def confirm_payment
|
||||||
data = JSON.parse(request.body.read.to_s)
|
data = JSON.parse(request.body.read.to_s)
|
||||||
|
|
||||||
@ -26,6 +25,28 @@ class API::PaymentsController < API::ApiController
|
|||||||
return [200, { error: e.message }.to_json]
|
return [200, { error: e.message }.to_json]
|
||||||
end
|
end
|
||||||
|
|
||||||
return generate_payment_response(intent)
|
render generate_payment_response(intent)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def generate_payment_response(intent)
|
||||||
|
if intent.status == 'requires_action' && intent.next_action.type == 'use_stripe_sdk'
|
||||||
|
# Tell the client to handle the action
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
json: {
|
||||||
|
requires_action: true,
|
||||||
|
payment_intent_client_secret: intent.client_secret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif intent.status == 'succeeded'
|
||||||
|
# The payment didn’t need any additional actions and is completed!
|
||||||
|
# Handle post-payment fulfillment
|
||||||
|
{ status: 200, json: { success: true } }
|
||||||
|
else
|
||||||
|
# Invalid status
|
||||||
|
{ status: 500, json: { error: 'Invalid PaymentIntent status' } }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -146,6 +146,9 @@ Rails.application.routes.draw do
|
|||||||
|
|
||||||
# Fab-manager's version
|
# Fab-manager's version
|
||||||
get 'version' => 'version#show'
|
get 'version' => 'version#show'
|
||||||
|
|
||||||
|
# payments handling
|
||||||
|
post 'payments/confirm_payment' => 'payments/confirm_payment'
|
||||||
end
|
end
|
||||||
|
|
||||||
# rss
|
# rss
|
||||||
|
Loading…
x
Reference in New Issue
Block a user