Stripe Payments Continued
This commit is contained in:
parent
9763ef9c25
commit
a5e3cb84b7
@ -1,3 +1,4 @@
|
|||||||
|
using API.Errors;
|
||||||
using Core.Entities;
|
using Core.Entities;
|
||||||
using Core.Interfaces;
|
using Core.Interfaces;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -17,7 +18,9 @@ namespace API.Controllers
|
|||||||
[HttpPost("{basketId}")]
|
[HttpPost("{basketId}")]
|
||||||
public async Task<ActionResult<CustomerBasket>> CreateOrUpdatePaymentIntent(string basketId)
|
public async Task<ActionResult<CustomerBasket>> CreateOrUpdatePaymentIntent(string basketId)
|
||||||
{
|
{
|
||||||
return await _paymentService.CreateOrUpdatePaymentIntent(basketId);
|
var basket = await _paymentService.CreateOrUpdatePaymentIntent(basketId);
|
||||||
|
if(basket == null) return BadRequest(new ApiResponse(400, "Problem with your basket"));
|
||||||
|
return basket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,5 +10,7 @@ namespace API.Dtos
|
|||||||
public int? DeliveryMethodId { get; set; }
|
public int? DeliveryMethodId { get; set; }
|
||||||
public string ClientSecret { get; set; }
|
public string ClientSecret { get; set; }
|
||||||
public string PaymentItentId { get; set; }
|
public string PaymentItentId { get; set; }
|
||||||
|
|
||||||
|
public decimal ShippingPrice { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,5 +21,6 @@ namespace Core.Entities
|
|||||||
public int? DeliveryMethodId { get; set; }
|
public int? DeliveryMethodId { get; set; }
|
||||||
public string ClientSecret { get; set; }
|
public string ClientSecret { get; set; }
|
||||||
public string PaymentItentId { get; set; }
|
public string PaymentItentId { get; set; }
|
||||||
|
public decimal ShippingPrice { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,13 +6,14 @@ namespace Core.Entities.OrderAggregate
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order(IReadOnlyList<OrderItem> orderItems, string buyerEmail, Address shipToAddress, DeliveryMethod deliveryMethod, decimal subtotal)
|
public Order(IReadOnlyList<OrderItem> orderItems, string buyerEmail, Address shipToAddress, DeliveryMethod deliveryMethod, decimal subtotal, string paymentIntentId)
|
||||||
{
|
{
|
||||||
BuyerEmail = buyerEmail;
|
BuyerEmail = buyerEmail;
|
||||||
ShipToAddress = shipToAddress;
|
ShipToAddress = shipToAddress;
|
||||||
DeliveryMethod = deliveryMethod;
|
DeliveryMethod = deliveryMethod;
|
||||||
OrderItems = orderItems;
|
OrderItems = orderItems;
|
||||||
Subtotal = subtotal;
|
Subtotal = subtotal;
|
||||||
|
PaymentIntentId = paymentIntentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string BuyerEmail { get; set; }
|
public string BuyerEmail { get; set; }
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
using Core.Entities.OrderAggregate;
|
||||||
|
|
||||||
|
namespace Core.Specifications
|
||||||
|
{
|
||||||
|
public class OrderByPaymentIntentIdWithItemsSpecification : BaseSpecification<Order>
|
||||||
|
{
|
||||||
|
public OrderByPaymentIntentIdWithItemsSpecification(string paymentIntentId) : base(o => o.PaymentIntentId == paymentIntentId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,9 +9,11 @@ namespace Infrastructure.Services
|
|||||||
{
|
{
|
||||||
private readonly IBasketRepository _basketRepo;
|
private readonly IBasketRepository _basketRepo;
|
||||||
private readonly IUnitOfWork _unitOfWork;
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
|
private readonly IPaymentService _paymentService;
|
||||||
|
|
||||||
public OrderService(IBasketRepository basketRepo, IUnitOfWork unitOfWork)
|
public OrderService(IBasketRepository basketRepo, IUnitOfWork unitOfWork, IPaymentService paymentService)
|
||||||
{
|
{
|
||||||
|
_paymentService = paymentService;
|
||||||
_unitOfWork = unitOfWork;
|
_unitOfWork = unitOfWork;
|
||||||
_basketRepo = basketRepo;
|
_basketRepo = basketRepo;
|
||||||
}
|
}
|
||||||
@ -29,11 +31,19 @@ namespace Infrastructure.Services
|
|||||||
}
|
}
|
||||||
var deliveryMethod = await _unitOfWork.Repository<DeliveryMethod>().GetByIdAsync(deliverMethodId);
|
var deliveryMethod = await _unitOfWork.Repository<DeliveryMethod>().GetByIdAsync(deliverMethodId);
|
||||||
var subtotal = items.Sum(item => item.Price * item.Quantity);
|
var subtotal = items.Sum(item => item.Price * item.Quantity);
|
||||||
var order = new Order(items, buyerEmail, shippingAddress, deliveryMethod, subtotal);
|
var spec = new OrderByPaymentIntentIdWithItemsSpecification(basket.PaymentItentId);
|
||||||
|
var existingOrder = await _unitOfWork.Repository<Order>().GetEntityWithSpec(spec);
|
||||||
|
if(existingOrder != null)
|
||||||
|
{
|
||||||
|
_unitOfWork.Repository<Order>().Delete(existingOrder);
|
||||||
|
await _paymentService.CreateOrUpdatePaymentIntent(basket.PaymentItentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
var order = new Order(items, buyerEmail, shippingAddress, deliveryMethod, subtotal, basket.PaymentItentId);
|
||||||
_unitOfWork.Repository<Order>().Add(order);
|
_unitOfWork.Repository<Order>().Add(order);
|
||||||
var result = await _unitOfWork.Complete();
|
var result = await _unitOfWork.Complete();
|
||||||
if(result <= 0) return null;
|
if(result <= 0) return null;
|
||||||
await _basketRepo.DeleteBasketAsysnc(basketId);
|
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ namespace Infrastructure.Services
|
|||||||
{
|
{
|
||||||
StripeConfiguration.ApiKey = _config["StripeSettings:SecretKey"];
|
StripeConfiguration.ApiKey = _config["StripeSettings:SecretKey"];
|
||||||
var basket = await _basketRepository.GetBasketAsync(basketId);
|
var basket = await _basketRepository.GetBasketAsync(basketId);
|
||||||
|
if(basket == null) return null;
|
||||||
var shippingPrice = 0m;
|
var shippingPrice = 0m;
|
||||||
|
|
||||||
if(basket.DeliveryMethodId.HasValue){
|
if(basket.DeliveryMethodId.HasValue){
|
||||||
|
@ -19,15 +19,28 @@ export class BasketService {
|
|||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
|
createPaymentIntent(){
|
||||||
|
return this.http.post(this.baseUrl + 'payments/' + this.getCurrentBasketValue().id, {}).pipe(
|
||||||
|
map((basket: IBasket) => {
|
||||||
|
this.basketSource.next(basket);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
setShippingPrice(deliveryMethod: IDeliveryMethods){
|
setShippingPrice(deliveryMethod: IDeliveryMethods){
|
||||||
this.shipping = deliveryMethod.price;
|
this.shipping = deliveryMethod.price;
|
||||||
|
const basket = this.getCurrentBasketValue();
|
||||||
|
basket.deliveryMethodId = deliveryMethod.id;
|
||||||
|
basket.shippingPrice = deliveryMethod.price;
|
||||||
this.calculateTotals();
|
this.calculateTotals();
|
||||||
|
this.setBasket(basket);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBasket(id: string){
|
getBasket(id: string){
|
||||||
return this.http.get(this.baseUrl + 'basket?id=' + id).pipe(
|
return this.http.get(this.baseUrl + 'basket?id=' + id).pipe(
|
||||||
map((basket: IBasket) => {
|
map((basket: IBasket) => {
|
||||||
this.basketSource.next(basket);
|
this.basketSource.next(basket);
|
||||||
|
this.shipping = basket.shippingPrice;
|
||||||
this.calculateTotals();
|
this.calculateTotals();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,30 @@
|
|||||||
<p>checkout-payments works!</p>
|
<div class="mt-5 pb-3" [formGroup]="checkoutForm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-12" formGroupName="paymentForm">
|
||||||
|
<app-text-inputs [label]="'Name on card'" formControlName="nameOnCard"></app-text-inputs>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-6">
|
||||||
|
<div class="form-control py-3" #cardNumber></div>
|
||||||
|
<ng-container *ngIf="cardErrors">
|
||||||
|
<span class="text-warning">
|
||||||
|
{{cardErrors}}
|
||||||
|
</span>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-3">
|
||||||
|
<div class="form-control py-3" #cardExpiry></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-3">
|
||||||
|
<div class="form-control py-3" #cardCvc></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="float-none d-flex justify-content-between flex-column flex-lg-row mb-5">
|
<div class="float-none d-flex justify-content-between flex-column flex-lg-row mb-5">
|
||||||
<button class="btn btn-outline-primary" cdkStepperPrevious>
|
<button class="btn btn-outline-primary" cdkStepperPrevious>
|
||||||
<i class="fa fa-angle-left"></i> Back to Review
|
<i class="fa fa-angle-left"></i> Back to Review
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary" (click)="submitOrder()">
|
<button [disabled]="loading" class="btn btn-primary" (click)="submitOrder()">
|
||||||
Complete Checkout <i class="fa fa-angle-right"></i>
|
Complete Checkout <i class="fa fa-angle-right"></i>
|
||||||
|
<i *ngIf="loading" class="fa fa-spinner fa-spin"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,43 +1,106 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { FormGroup } from '@angular/forms';
|
import { FormGroup } from '@angular/forms';
|
||||||
import { NavigationExtras, Router } from '@angular/router';
|
import { NavigationExtras, Router } from '@angular/router';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
|
import { lastValueFrom } from 'rxjs';
|
||||||
import { BasketService } from 'src/app/basket/basket.service';
|
import { BasketService } from 'src/app/basket/basket.service';
|
||||||
import { IBasket } from 'src/app/shared/models/baskset';
|
import { IBasket } from 'src/app/shared/models/baskset';
|
||||||
import { IOrder } from 'src/app/shared/models/order';
|
import { IOrder } from 'src/app/shared/models/order';
|
||||||
import { CheckoutService } from '../checkout.service';
|
import { CheckoutService } from '../checkout.service';
|
||||||
|
|
||||||
|
declare var Stripe;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-checkout-payments',
|
selector: 'app-checkout-payments',
|
||||||
templateUrl: './checkout-payments.component.html',
|
templateUrl: './checkout-payments.component.html',
|
||||||
styleUrls: ['./checkout-payments.component.scss']
|
styleUrls: ['./checkout-payments.component.scss']
|
||||||
})
|
})
|
||||||
export class CheckoutPaymentsComponent implements OnInit {
|
export class CheckoutPaymentsComponent implements AfterViewInit, OnDestroy {
|
||||||
@Input() checkoutForm: FormGroup;
|
@Input() checkoutForm: FormGroup;
|
||||||
|
@ViewChild('cardNumber', {static: true}) cardNumberElement: ElementRef;
|
||||||
|
@ViewChild('cardExpiry', {static: true}) cardExpiryElement: ElementRef;
|
||||||
|
@ViewChild('cardCvc', {static: true}) cardCvcElement: ElementRef;
|
||||||
|
stripe: any;
|
||||||
|
cardNumber: any;
|
||||||
|
cardExpiry: any;
|
||||||
|
cardCvc: any;
|
||||||
|
cardErrors: any;
|
||||||
|
cardHandler = this.onChange.bind(this);
|
||||||
|
loading = false;
|
||||||
|
|
||||||
constructor(private basketService: BasketService, private checkoutService: CheckoutService, private toastr: ToastrService, private router: Router) { }
|
constructor(private basketService: BasketService, private checkoutService: CheckoutService, private toastr: ToastrService, private router: Router) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngAfterViewInit(): void {
|
||||||
|
this.stripe = Stripe('pk_test_51L4B2fKnYx7tVZlJDJxQ56Wrjip0xv6ieenwhyzoM8hPu2iHRg581JBJAwOpMoQLlsWg7uSs3izk7xQv0xpT5sK000HDZNIA1l');
|
||||||
|
const elements = this.stripe.elements();
|
||||||
|
|
||||||
|
this.cardNumber = elements.create('cardNumber');
|
||||||
|
this.cardNumber.mount(this.cardNumberElement.nativeElement);
|
||||||
|
this.cardNumber.addEventListener('change', this.cardHandler);
|
||||||
|
|
||||||
|
this.cardExpiry = elements.create('cardExpiry');
|
||||||
|
this.cardExpiry.mount(this.cardExpiryElement.nativeElement);
|
||||||
|
this.cardExpiry.addEventListener('change', this.cardHandler);
|
||||||
|
|
||||||
|
this.cardCvc = elements.create('cardCvc');
|
||||||
|
this.cardCvc.mount(this.cardCvcElement.nativeElement);
|
||||||
|
this.cardCvc.addEventListener('change', this.cardHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.cardNumber.destroy();
|
||||||
|
this.cardExpiry.destroy();
|
||||||
|
this.cardCvc.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange({error}) {
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
this.cardErrors = error.message;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
this.cardErrors = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async submitOrder(){
|
||||||
|
this.loading = true;
|
||||||
|
const basket = this.basketService.getCurrentBasketValue();
|
||||||
|
try {
|
||||||
|
const createdOrder = await this.createOrder(basket);
|
||||||
|
const paymentResult = await this.confirmPaymentWithStripe(basket);
|
||||||
|
|
||||||
|
if(paymentResult.paymentIntent)
|
||||||
|
{
|
||||||
|
this.basketService.deleteLocalBasket(basket.id);
|
||||||
|
const navigationExtras: NavigationExtras = {state: createdOrder};
|
||||||
|
this.router.navigate(['checkout/success'], navigationExtras);
|
||||||
|
} else {
|
||||||
|
this.toastr.error(paymentResult.error.message);
|
||||||
|
}
|
||||||
|
this.loading = false;
|
||||||
|
} catch(error) {
|
||||||
|
console.log(error);
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
submitOrder(){
|
private async confirmPaymentWithStripe(basket: IBasket) {
|
||||||
const basket = this.basketService.getCurrentBasketValue();
|
return this.stripe.confirmCardPayment(basket.clientSecret, {
|
||||||
const orderToCreate = this.getOrderToCreate(basket);
|
payment_method: {
|
||||||
this.checkoutService.createOrder(orderToCreate).subscribe({
|
card: this.cardNumber,
|
||||||
next: (order: IOrder) => {
|
billing_details: {
|
||||||
this.toastr.success('Order created successfully');
|
name: this.checkoutForm.get('paymentForm').get('nameOnCard').value
|
||||||
this.basketService.deleteLocalBasket(basket.id);
|
}
|
||||||
const navigationExtras: NavigationExtras = {state: order};
|
}
|
||||||
this.router.navigate(['checkout/success'], navigationExtras);
|
|
||||||
},
|
|
||||||
error: (e: any) => {
|
|
||||||
this.toastr.error(e.message);
|
|
||||||
console.log(e);
|
|
||||||
},
|
|
||||||
complete: () => { console.log('completed') }
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async createOrder(basket: IBasket) {
|
||||||
|
const orderToCreate = this.getOrderToCreate(basket);
|
||||||
|
return lastValueFrom(this.checkoutService.createOrder(orderToCreate));
|
||||||
|
}
|
||||||
|
|
||||||
private getOrderToCreate(basket: IBasket) {
|
private getOrderToCreate(basket: IBasket) {
|
||||||
return {
|
return {
|
||||||
basketId: basket.id,
|
basketId: basket.id,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<button class="btn btn-outline-primary" cdkStepperPrevious>
|
<button class="btn btn-outline-primary" cdkStepperPrevious>
|
||||||
<i class="fa fa-angle-left"></i> Back to Delivery
|
<i class="fa fa-angle-left"></i> Back to Delivery
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary" cdkStepperNext>
|
<button class="btn btn-primary" (click)="createPaymentIntent()">
|
||||||
Payment Options <i class="fa fa-angle-right"></i>
|
Payment Options <i class="fa fa-angle-right"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { CdkStepper } from '@angular/cdk/stepper';
|
||||||
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { ToastrService } from 'ngx-toastr';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { BasketService } from 'src/app/basket/basket.service';
|
import { BasketService } from 'src/app/basket/basket.service';
|
||||||
import { IBasket } from 'src/app/shared/models/baskset';
|
import { IBasket } from 'src/app/shared/models/baskset';
|
||||||
@ -9,12 +11,23 @@ import { IBasket } from 'src/app/shared/models/baskset';
|
|||||||
styleUrls: ['./checkout-review.component.scss']
|
styleUrls: ['./checkout-review.component.scss']
|
||||||
})
|
})
|
||||||
export class CheckoutReviewComponent implements OnInit {
|
export class CheckoutReviewComponent implements OnInit {
|
||||||
|
@Input() appStepper: CdkStepper;
|
||||||
basket$: Observable<IBasket>;
|
basket$: Observable<IBasket>;
|
||||||
|
|
||||||
constructor(private basketService: BasketService) { }
|
constructor(private basketService: BasketService, private toastrService: ToastrService) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.basket$ = this.basketService.basket$;
|
this.basket$ = this.basketService.basket$;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createPaymentIntent(){
|
||||||
|
return this.basketService.createPaymentIntent().subscribe({
|
||||||
|
next: (response: any) => {
|
||||||
|
this.appStepper.next();
|
||||||
|
},
|
||||||
|
error: (e: any ) => { console.log(e); },
|
||||||
|
complete: () => { console.log('completed'); }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<app-stepper [linearModeSelected]="false" #appStepper>
|
<app-stepper [linearModeSelected]="true" #appStepper>
|
||||||
<cdk-step [label]="'Address'" [completed]="(checkoutForm.get('addressForm')).valid">
|
<cdk-step [label]="'Address'" [completed]="(checkoutForm.get('addressForm')).valid">
|
||||||
<app-checkout-address [checkoutForm]="checkoutForm"></app-checkout-address>
|
<app-checkout-address [checkoutForm]="checkoutForm"></app-checkout-address>
|
||||||
</cdk-step>
|
</cdk-step>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<app-checkout-delivery [checkoutForm]="checkoutForm"></app-checkout-delivery>
|
<app-checkout-delivery [checkoutForm]="checkoutForm"></app-checkout-delivery>
|
||||||
</cdk-step>
|
</cdk-step>
|
||||||
<cdk-step [label]="'Review'">
|
<cdk-step [label]="'Review'">
|
||||||
<app-checkout-review></app-checkout-review>
|
<app-checkout-review [appStepper]="appStepper"></app-checkout-review>
|
||||||
</cdk-step>
|
</cdk-step>
|
||||||
<cdk-step [label]="'Payment'">
|
<cdk-step [label]="'Payment'">
|
||||||
<app-checkout-payments [checkoutForm]="checkoutForm"></app-checkout-payments>
|
<app-checkout-payments [checkoutForm]="checkoutForm"></app-checkout-payments>
|
||||||
|
@ -20,6 +20,7 @@ export class CheckoutComponent implements OnInit {
|
|||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.createCheckoutForm();
|
this.createCheckoutForm();
|
||||||
this.getAddressFormValues();
|
this.getAddressFormValues();
|
||||||
|
this.getDeliveryMethodValue();
|
||||||
this.basketTotals$ = this.basketService.basketTotal$;
|
this.basketTotals$ = this.basketService.basketTotal$;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ export class CheckoutComponent implements OnInit {
|
|||||||
deliveryForm: this.fb.group({
|
deliveryForm: this.fb.group({
|
||||||
deliveryMethod: [null, Validators.required]
|
deliveryMethod: [null, Validators.required]
|
||||||
}),
|
}),
|
||||||
paymenForm: this.fb.group({
|
paymentForm: this.fb.group({
|
||||||
nameOnCard: [null, Validators.required]
|
nameOnCard: [null, Validators.required]
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -54,4 +55,11 @@ export class CheckoutComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDeliveryMethodValue(){
|
||||||
|
const basket = this.basketService.getCurrentBasketValue();
|
||||||
|
if(basket.deliveryMethodId !== null){
|
||||||
|
this.checkoutForm.get('deliveryForm').get('deliveryMethod').patchValue(basket.deliveryMethodId.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,14 @@ export class LoadingInterceptor implements HttpInterceptor {
|
|||||||
constructor(private busyService: BusyService) {}
|
constructor(private busyService: BusyService) {}
|
||||||
|
|
||||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
if(!req.url.includes('emailexists')){
|
if(req.method === 'POST' && req.url.includes('orders')){
|
||||||
this.busyService.busy();
|
return next.handle(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(req.url.includes('emailexists')){
|
||||||
|
return next.handle(req);
|
||||||
|
}
|
||||||
|
this.busyService.busy();
|
||||||
return next.handle(req).pipe(
|
return next.handle(req).pipe(
|
||||||
delay(1000),
|
delay(1000),
|
||||||
finalize(()=> {
|
finalize(()=> {
|
||||||
|
@ -13,6 +13,10 @@ export interface IBasketItem {
|
|||||||
export interface IBasket {
|
export interface IBasket {
|
||||||
id: string;
|
id: string;
|
||||||
items: IBasketItem[];
|
items: IBasketItem[];
|
||||||
|
clientSecret?: string;
|
||||||
|
paymentIntentId?: string;
|
||||||
|
deliveryMethodId?: number;
|
||||||
|
shippingPrice?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Basket implements IBasket {
|
export class Basket implements IBasket {
|
||||||
|
@ -9,5 +9,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user