mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
handle successfull stripe payment
This commit is contained in:
parent
1e43dc9518
commit
96b1cfcbc7
@ -4,10 +4,11 @@ import { PaymentMethod } from "@stripe/stripe-js";
|
||||
import PaymentAPI from '../api/payment';
|
||||
import { CartItems, PaymentConfirmation } from '../models/payment';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Reservation } from '../models/reservation';
|
||||
|
||||
interface StripeFormProps {
|
||||
onSubmit: () => void,
|
||||
onSuccess: (paymentMethod: PaymentMethod) => void,
|
||||
onSuccess: (result: PaymentMethod|PaymentConfirmation) => void,
|
||||
onError: (message: string) => void,
|
||||
className?: string,
|
||||
processPayment?: boolean,
|
||||
@ -48,7 +49,7 @@ export const StripeForm: React.FC<StripeFormProps> = ({ onSubmit, onSuccess, onE
|
||||
if (processPayment) {
|
||||
// process the full payment pipeline, including SCA validation
|
||||
const res = await PaymentAPI.confirm(paymentMethod.id, cartItems);
|
||||
await handleServerConfirmation(res, paymentMethod);
|
||||
await handleServerConfirmation(res);
|
||||
} else {
|
||||
// we don't want to process the payment, only return the payment method
|
||||
onSuccess(paymentMethod);
|
||||
@ -58,8 +59,12 @@ export const StripeForm: React.FC<StripeFormProps> = ({ onSubmit, onSuccess, onE
|
||||
|
||||
/**
|
||||
* Process the server response about the Strong-customer authentication (SCA)
|
||||
* @param response can be a PaymentConfirmation, or a Reservation (if the reservation succeeded), or a Subscription (if the subscription succeeded)
|
||||
* @see app/controllers/api/payments_controller.rb#on_reservation_success
|
||||
* @see app/controllers/api/payments_controller.rb#on_subscription_success
|
||||
* @see app/controllers/api/payments_controller.rb#generate_payment_response
|
||||
*/
|
||||
const handleServerConfirmation = async (response: PaymentConfirmation, paymentMethod: PaymentMethod) => {
|
||||
const handleServerConfirmation = async (response: PaymentConfirmation|any) => {
|
||||
if (response.error) {
|
||||
if (response.error.statusText) {
|
||||
onError(response.error.statusText);
|
||||
@ -76,13 +81,13 @@ export const StripeForm: React.FC<StripeFormProps> = ({ onSubmit, onSuccess, onE
|
||||
// The PaymentIntent can be confirmed again on the server
|
||||
try {
|
||||
const confirmation = await PaymentAPI.confirm(result.paymentIntent.id, cartItems);
|
||||
await handleServerConfirmation(confirmation, paymentMethod);
|
||||
await handleServerConfirmation(confirmation);
|
||||
} catch (e) {
|
||||
onError(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onSuccess(paymentMethod);
|
||||
onSuccess(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ import { StripeForm } from './stripe-form';
|
||||
import stripeLogo from '../../../images/powered_by_stripe.png';
|
||||
import mastercardLogo from '../../../images/mastercard.png';
|
||||
import visaLogo from '../../../images/visa.png';
|
||||
import { CartItems } from '../models/payment';
|
||||
import { CartItems, PaymentConfirmation } from '../models/payment';
|
||||
import WalletAPI from '../api/wallet';
|
||||
import PriceAPI from '../api/price';
|
||||
|
||||
@ -33,7 +33,7 @@ declare var Fablab: IFablab;
|
||||
interface StripeModalProps {
|
||||
isOpen: boolean,
|
||||
toggleModal: () => void,
|
||||
afterSuccess: (paymentMethod: PaymentMethod) => void,
|
||||
afterSuccess: (result: PaymentMethod|PaymentConfirmation) => void,
|
||||
cartItems: CartItems,
|
||||
currentUser: User,
|
||||
schedule: PaymentSchedule,
|
||||
@ -140,9 +140,9 @@ const StripeModal: React.FC<StripeModalProps> = ({ isOpen, toggleModal, afterSuc
|
||||
/**
|
||||
* After sending the form with success, process the resulting payment method
|
||||
*/
|
||||
const handleFormSuccess = async (paymentMethod: PaymentMethod): Promise<void> => {
|
||||
const handleFormSuccess = async (result: PaymentMethod|PaymentConfirmation): Promise<void> => {
|
||||
setSubmitState(false);
|
||||
afterSuccess(paymentMethod);
|
||||
afterSuccess(result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -735,19 +735,6 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
|
||||
* @param user {Object} user associated with the slot
|
||||
*/
|
||||
const updateMachineSlot = function (slot, reservation, user) {
|
||||
/* TODO, FIXME
|
||||
machines.js.erb:741 Uncaught (in promise) TypeError: Cannot read property 'slots' of undefined
|
||||
at updateMachineSlot (machines.js.erb:741)
|
||||
at machines.js.erb:664
|
||||
at Object.forEach (angular.js:386)
|
||||
at Scope.$scope.afterPayment (machines.js.erb:652)
|
||||
at afterPayment (cart.js:884)
|
||||
at $scope.afterStripeSuccess (cart.js:338)
|
||||
at _callee$ (stripe-modal.tsx:145)
|
||||
at tryCatch (runtime.js:63)
|
||||
at Generator.invoke [as _invoke] (runtime.js:293)
|
||||
at Generator.next (runtime.js:118)
|
||||
*/
|
||||
angular.forEach(reservation.slots, function (s) {
|
||||
if (slot.start.isSame(s.start_at)) {
|
||||
slot.slot_id = s.id;
|
||||
|
@ -70,13 +70,13 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
// Payment schedule
|
||||
$scope.schedule = {
|
||||
requested_schedule: false, // does the user requests a payment schedule for his subscription
|
||||
payment_schedule: null // the effective computed payment schedule
|
||||
payment_schedule: undefined // the effective computed payment schedule
|
||||
};
|
||||
|
||||
// online payments (stripe)
|
||||
$scope.stripe = {
|
||||
showModal: false,
|
||||
cartItems: null
|
||||
cartItems: undefined
|
||||
};
|
||||
|
||||
// currently logged-in user
|
||||
@ -327,10 +327,11 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
|
||||
/**
|
||||
* Invoked atfer a successful Stripe payment
|
||||
* @param result {*} may be a reservation or a subscription
|
||||
*/
|
||||
$scope.afterStripeSuccess = () => {
|
||||
$scope.afterStripeSuccess = (result) => {
|
||||
$scope.toggleStripeModal();
|
||||
afterPayment($scope.reservation);
|
||||
afterPayment(result);
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
@ -638,9 +639,9 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
|
||||
/**
|
||||
* Format the parameters expected by /api/prices/compute or /api/reservations and return the resulting object
|
||||
* @param request {{reservation: object}|{subscription: object}} as returned by mkReservation()
|
||||
* @param coupon {Object} Coupon as returned from the API
|
||||
* @return {{reservation:Object, subscription: Object, coupon_code:string}}
|
||||
* @param request {{reservation: *}|{subscription: *}} as returned by mkReservation()
|
||||
* @param coupon {{code: string}} Coupon as returned from the API
|
||||
* @return {CartItems}
|
||||
*/
|
||||
const mkRequestParams = function (request, coupon) {
|
||||
return Object.assign({
|
||||
@ -870,28 +871,28 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
|
||||
/**
|
||||
* Actions to run after the payment was successful
|
||||
* @param reservation {Object} may be a reservation or a subscription
|
||||
* @param paymentResult {*} may be a reservation or a subscription
|
||||
*/
|
||||
const afterPayment = function (reservation) {
|
||||
const afterPayment = function (paymentResult) {
|
||||
// we set the cart content as 'paid' to display a summary of the transaction
|
||||
$scope.events.paid = $scope.events.reserved;
|
||||
$scope.amountPaid = $scope.amountTotal;
|
||||
// we call the external callback if present
|
||||
if (typeof $scope.afterPayment === 'function') { $scope.afterPayment(reservation); }
|
||||
if (typeof $scope.afterPayment === 'function') { $scope.afterPayment(paymentResult); }
|
||||
// we reset the coupon, and the cart content, and we unselect the slot
|
||||
$scope.coupon.applied = null;
|
||||
$scope.coupon.applied = undefined;
|
||||
if ($scope.slot) {
|
||||
// reservation (+ subscription)
|
||||
$scope.slot = null;
|
||||
$scope.slot = undefined;
|
||||
$scope.events.reserved = [];
|
||||
} else {
|
||||
// subscription only
|
||||
$scope.events = {};
|
||||
}
|
||||
$scope.paidPlan = $scope.selectedPlan;
|
||||
$scope.selectedPlan = null;
|
||||
$scope.selectedPlan = undefined;
|
||||
$scope.schedule.requested_schedule = false;
|
||||
$scope.schedule.payment_schedule = null;
|
||||
$scope.schedule.payment_schedule = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,7 @@ export interface PaymentConfirmation {
|
||||
success?: boolean,
|
||||
error?: {
|
||||
statusText: string
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export enum PaymentMethod {
|
||||
@ -15,12 +15,12 @@ export enum PaymentMethod {
|
||||
}
|
||||
|
||||
export interface CartItems {
|
||||
reservation: Reservation,
|
||||
subscription: {
|
||||
reservation?: Reservation,
|
||||
subscription?: {
|
||||
plan_id: number,
|
||||
user_id: number,
|
||||
payment_schedule: boolean,
|
||||
payment_method: PaymentMethod
|
||||
},
|
||||
coupon_code: string
|
||||
coupon_code?: string
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user