भुगतान अनुरोध एपीआई और कोणीय के साथ इंटरनेट घोषणात्मक खरीदारी

आपने Google पे, Apple पे या अपने ब्राउज़र में पूर्वनिर्धारित कार्ड का उपयोग करके एक क्लिक में वेबसाइट पर कब तक भुगतान किया है?

मैं शायद ही कभी मिलता हूं।

इसके विपरीत: हर नया ऑनलाइन स्टोर मुझे एक और मोल्ड प्रदान करता है। और मुझे हर बार अपने कार्ड की खोज के लिए इसे साइट से डेटा पुनर्मुद्रण करने के लिए सावधानी से खोजना होगा। अगले दिन मैं किसी अन्य स्टोर में कुछ के लिए भुगतान करना चाहूंगा और इस प्रक्रिया को दोहराऊंगा।

यह बहुत सुविधाजनक नहीं है। विशेष रूप से जब आप एक विकल्प के बारे में जानते हैं: पिछले कुछ वर्षों में, भुगतान अनुरोध एपीआई मानक इस समस्या को आधुनिक ब्राउज़रों में हल करना आसान बनाता है।

आइए समझते हैं कि इसका उपयोग क्यों नहीं किया जाता है, और इसके साथ काम को सरल बनाने का प्रयास करें।



तुम्हारी किस बारे में बोलने की इच्छा थी?


लगभग सभी आधुनिक ब्राउज़र भुगतान अनुरोध एपीआई मानक को लागू करते हैं यह आपको ब्राउज़र में एक मोडल विंडो को कॉल करने की अनुमति देता है जिसके माध्यम से उपयोगकर्ता कुछ ही सेकंड में भुगतान कर सकता है। यह ब्राउज़र से एक नियमित कार्ड के साथ क्रोम में कैसे दिख सकता है:



और यहां यह ऐप्पल पे के माध्यम से एक फिंगरप्रिंट के साथ भुगतान करते समय सफारी में है:



यह न केवल तेज़ है, बल्कि कार्यात्मक भी है: खिड़की आपको पूरे ऑर्डर पर और व्यक्तिगत वस्तुओं और सेवाओं के अंदर जानकारी प्रदर्शित करने की अनुमति देती है। उसे, आपको ग्राहक की जानकारी और वितरण विवरण को स्पष्ट करने की अनुमति देता है। अनुरोध बनाते समय यह सब अनुकूलित है, हालांकि प्रदान की गई एपीआई की सुविधा बल्कि विवादास्पद है।

कोणीय में उपयोग कैसे करें?


भुगतान अनुरोध API का उपयोग करने के लिए कोणीय सार प्रदान नहीं करता है। कोणीय में बॉक्स से इसका उपयोग करने का सबसे सुरक्षित तरीका है कि डिपेंडेंसी इंजेक्शन तंत्र से दस्तावेज़ प्राप्त करें, इससे विंडो ऑब्जेक्ट प्राप्त करें और window.PaymentRequest के साथ काम करें।

import {DOCUMENT} from '@angular/common';
import {Inject, Injectable} from '@angular/core';
 
@Injectable()
export class PaymentService {
   constructor(
       @Inject(DOCUMENT)
       private readonly documentRef: Document,
   ) {}
 
   pay(
       methodData: PaymentMethodData[],
       details: PaymentDetailsInit,
       options: PaymentOptions = {},
   ): Promise<PaymentResponse> {
       if (
           this.documentRef.defaultView === null ||
           !('PaymentRequest' in this.documentRef.defaultView)
       ) {
           return Promise.reject(new Error('PaymentRequest is not supported'));
       }
 
       const gateway = new PaymentRequest(methodData, details, options);
 
       return gateway
           .canMakePayment()
           .then(canPay =>
               canPay
                   ? gateway.show()
                   : Promise.reject(
                         new Error('Payment Request cannot make the payment'),
                     ),
           );
   }
}

यदि आप सीधे भुगतान अनुरोध का उपयोग करते हैं, तो अंतर्निहित निर्भरता की सभी समस्याएं दिखाई देती हैं: कोड का परीक्षण करना कठिन हो जाता है, आवेदन SSR में फट जाता है क्योंकि भुगतान अनुरोध मौजूद नहीं है। हम बिना किसी अमूर्त के वैश्विक वस्तु की आशा करते हैं।

हम ले जा सकते हैं खिड़की टोकन से @ एनजी-वेब-apis / आम सुरक्षित रूप से करने के लिए डि से वैश्विक वस्तु मिलता है। अब एक नया PAYMENT_REQUEST_SUPPORT जोड़ें यह आपको उपयोग करने से पहले भुगतान अनुरोध एपीआई के समर्थन की जांच करने की अनुमति देगा, और अब हमारे पास ऐसे वातावरण में आकस्मिक एपीआई कॉल कभी नहीं होगा जो इसका समर्थन नहीं करता है।

export const PAYMENT_REQUEST_SUPPORT = new InjectionToken<boolean>(
   'Is Payment Request Api supported?',
   {
       factory: () => !!inject(WINDOW).PaymentRequest,
   },
);

export class PaymentRequestService {
   constructor(
       @Inject(PAYMENT_REQUEST_SUPPORT) private readonly supported: boolean,
       ...
    ) {}
 
    request(...): Promise<PaymentResponse> {
       if (!this.supported) {
           return Promise.reject(
               new Error('Payment Request is not supported in your browser'),
           );
       } 
      ...
   }

आइए, कोणीय शैली में लिखें


ऊपर वर्णित दृष्टिकोण के साथ, हम काफी सुरक्षित रूप से भुगतान के साथ काम कर सकते हैं, लेकिन प्रयोज्य अभी भी एक नंगे एपीआई ब्राउज़र के समान स्तर पर है: हम तीन मापदंडों के साथ एक विधि कहते हैं, एक साथ बहुत सारे डेटा एकत्र करते हैं और अंत में कॉल करने के लिए वांछित प्रारूप में लाते हैं। भुगतान का तरीका।

लेकिन कोणीय की दुनिया में, हम सुविधाजनक सार के आदी हैं: एक निर्भरता इंजेक्शन तंत्र, सेवाएं, निर्देश और धाराएं। आइए एक घोषणात्मक समाधान देखें जो भुगतान अनुरोध एपीआई का उपयोग तेज और आसान करता है:



इस उदाहरण में, टोकरी इस प्रकार है:

<div waPayment [paymentTotal]="total">
   <div
       *ngFor="let cartItem of shippingCart"
       waPaymentItem
       [paymentLabel]="cartItem.label"
       [paymentAmount]="cartItem.amount"
   >
       {{ cartItem.label }} ({{ cartItem.amount.value }} {{ cartItem.amount.currency }})
   </div>
 
   <b>Total:</b>  {{ totalSum }} ₽
 
   <button
       [disabled]="shippingCart.length === 0"
       (waPaymentSubmit)="onPayment($event)"
       (waPaymentError)="onPaymentError($event)"
   >
       Buy
   </button>
</div>

तीन निर्देशों के लिए सब कुछ काम करता है:


इसलिए हमें भुगतान खोलने और इसके परिणाम को संसाधित करने के लिए एक सरल और सुविधाजनक इंटरफ़ेस मिलता है। और यह कोणीय मार्ग के सभी कैनन के अनुसार काम करता है।

निर्देश स्वयं एक सरल तरीके से जुड़े हुए हैं:

  • भुगतान निर्देश, ContentChildren और implements PaymentDetailsInit - भुगतान अनुरोध API के साथ काम करते समय आवश्यक तर्कों में से एक का उपयोग करके अपने भीतर सभी सामान एकत्र करता है।

@Directive({
   selector: '[waPayment][paymentTotal]',
})
export class PaymentDirective implements PaymentDetailsInit {
   ...
   @ContentChildren(PaymentItemDirective)
   set paymentItems(items: QueryList<PaymentItem>) {
       this.displayItems = items.toArray();
   }
 
   displayItems?: PaymentItem[];
}

  • आउटपुट निर्देश, जो एक बटन पर क्लिक करता है और अंतिम भुगतान परिणाम का उत्सर्जन करता है, डिपेंडेंसी इंजेक्शन पेड़ से भुगतान निर्देश, साथ ही भुगतान के तरीके और अतिरिक्त विकल्प जो डीआई टोकन द्वारा निर्धारित किए जाते हैं, बाहर खींचता है।

@Directive({
   selector: '[waPaymentSubmit]',
})
export class PaymentSubmitDirective {
   @Output()
   waPaymentSubmit: Observable<PaymentResponse>;
 
   @Output()
   waPaymentError: Observable<Error | DOMException>;
 
   constructor(
       @Inject(PaymentDirective) paymentHost: PaymentDetailsInit,
       @Inject(PaymentRequestService) paymentRequest: PaymentRequestService,
       @Inject(ElementRef) {nativeElement}: ElementRef,
       @Inject(PAYMENT_METHODS) methods: PaymentMethodData[],
       @Inject(PAYMENT_OPTIONS) options: PaymentOptions,
   ) {
       const requests$ = fromEvent(nativeElement, 'click').pipe(
           switchMap(() =>
               from(paymentRequest.request({...paymentHost}, methods, options)).pipe(
                   catchError(error => of(error)),
               ),
           ),
           share(),
       );
 
       this.waPaymentSubmit = requests$.pipe(filter(response => !isError(response)));
       this.waPaymentError = requests$.pipe(filter(isError));
   }
}

टर्नकी समाधान


हमने लाइब्रेरी @ एनजी-वेब-एपिस / भुगतान-अनुरोध में वर्णित सभी विचारों को एकत्र और कार्यान्वित किया है :


यह एक टर्नकी समाधान है जो आपको भुगतान अनुरोध एपीआई के साथ सुरक्षित रूप से और जल्दी से सेवा के माध्यम से और ऊपर वर्णित प्रारूप में निर्देशों के माध्यम से काम करने की अनुमति देता है।

हमने इस लाइब्रेरी को @ एनजी-वेब-एपिस से प्रकाशित किया है, जो मुख्य रूप से एक घोषणात्मक शैली में मूल वेब एपीआई के लिए हल्के कोणीय आवरण के कार्यान्वयन में विशेषज्ञता वाला एक खुला स्रोत समूह है। हमारी साइट पर अन्य एपीआई कार्यान्वयन हैं जो बॉक्स से बाहर कोणीय में वितरित नहीं हैं, लेकिन आपकी रुचि हो सकती है।

All Articles