Como adaptar seu app de pagamento baseado na Web aos pagamentos da Web e oferecer uma melhor experiência do usuário aos clientes.
Depois que o app de pagamento for registrado, você poderá aceitar solicitações de pagamento dos comerciantes. Esta postagem explica como orquestrar uma transação de pagamento de um worker de serviço durante a execução (ou seja, quando uma janela é exibida e o usuário interage com ela).
"Mudanças de parâmetro de pagamento no momento da execução" se referem a um conjunto de eventos que permite que o merchant e o gerenciador de pagamentos troquem mensagens enquanto o usuário interage com o gerenciador de pagamentos. Saiba mais em Como processar informações de pagamento opcionais com um worker de serviço.
Receber um evento de solicitação de pagamento do comerciante
Quando um cliente escolhe pagar com seu app de pagamento baseado na Web e o comerciante
invoca
PaymentRequest.show()
,
o service worker recebe um evento paymentrequest
. Adicione um listener de eventos
ao service worker para capturar o evento e se preparar para a próxima ação.
[payment handler] service-worker.js:
…
let payment_request_event;
let resolver;
let client;
// `self` is the global object in service worker
self.addEventListener('paymentrequest', async e => {
if (payment_request_event) {
// If there's an ongoing payment transaction, reject it.
resolver.reject();
}
// Preserve the event for future use
payment_request_event = e;
…
O PaymentRequestEvent
preservado contém informações importantes sobre essa
transação:
Nome da propriedade | Descrição |
---|---|
topOrigin |
Uma string que indica a origem da página da Web de nível superior (geralmente o comerciante recebedor). Use isso para identificar a origem do comerciante. |
paymentRequestOrigin |
Uma string que indica a origem do invocador. Esse valor pode ser o mesmo que topOrigin quando o comerciante invoca a API Payment Request diretamente, mas pode ser diferente se a API for invocada em um iframe por um terceiro, como um gateway de pagamento.
|
paymentRequestId |
A propriedade id do PaymentDetailsInit fornecido à API Payment Request. Se o comerciante omitir, o navegador vai fornecer um ID gerado automaticamente.
|
methodData |
Os dados específicos da forma de pagamento fornecidos pelo comerciante como parte de PaymentMethodData .
Use esse valor para determinar os detalhes da transação de pagamento.
|
total |
O valor total fornecido pelo comerciante como parte de PaymentDetailsInit .
Use isso para criar uma interface que informe ao cliente o valor total a ser pago.
|
instrumentKey |
A chave de instrumento selecionada pelo usuário. Isso reflete o instrumentKey que você forneceu com antecedência. Uma string vazia indica que o usuário não especificou nenhum instrumento.
|
Abra a janela do gerenciador de pagamentos para exibir o front-end do app de pagamento baseado na Web
Quando um evento paymentrequest
é recebido, o app de pagamento pode abrir uma janela
de gerenciador de pagamento chamando PaymentRequestEvent.openWindow()
. A janela do
processador de pagamentos vai apresentar aos clientes a interface do seu app de pagamento, onde
eles podem fazer a autenticação, escolher o endereço de entrega e as opções e autorizar o
pagamento. Vamos abordar como escrever o código do front-end em Como processar pagamentos no
front-end de pagamentos (em breve).
Transmita uma promessa preservada para PaymentRequestEvent.respondWith()
para que ela possa
ser resolvida com um resultado de pagamento no futuro.
[payment handler] service-worker.js:
…
self.addEventListener('paymentrequest', async e => {
…
// Retain a promise for future resolution
// Polyfill for PromiseResolver is provided below.
resolver = new PromiseResolver();
// Pass a promise that resolves when payment is done.
e.respondWith(resolver.promise);
// Open the checkout page.
try {
// Open the window and preserve the client
client = await e.openWindow(checkoutURL);
if (!client) {
// Reject if the window fails to open
throw 'Failed to open window';
}
} catch (err) {
// Reject the promise on failure
resolver.reject(err);
};
});
…
É possível usar um polyfill PromiseResolver
conveniente para resolver uma promessa em
um momento arbitrário.
class PromiseResolver {
constructor() {
this.promise_ = new Promise((resolve, reject) => {
this.resolve_ = resolve;
this.reject_ = reject;
})
}
get promise() { return this.promise_ }
get resolve() { return this.resolve_ }
get reject() { return this.reject_ }
}
Trocar informações com o front-end
O worker de serviço do app de pagamento pode trocar mensagens com o front-end
do app de pagamento por meio de ServiceWorkerController.postMessage()
. Para receber mensagens
do front-end, detecte eventos message
.
[payment handler] service-worker.js:
// Define a convenient `postMessage()` method
const postMessage = (type, contents = {}) => {
if (client) client.postMessage({ type, ...contents });
}
Receber o sinal de pronto do front-end
Quando a janela do gerenciador de pagamento for aberta, o service worker vai esperar um sinal de estado pronto do front-end do app de pagamento. O worker de serviço pode transmitir informações importantes para o front-end quando estiver pronto.
[payment handler] frontend:
navigator.serviceWorker.controller.postMessage({
type: 'WINDOW_IS_READY'
});
[payment handler] service-worker.js:
…
// Received a message from the frontend
self.addEventListener('message', async e => {
let details;
try {
switch (e.data.type) {
// `WINDOW_IS_READY` is a frontend's ready state signal
case 'WINDOW_IS_READY':
const { total } = payment_request_event;
…
Transmitir os detalhes da transação para o front-end
Agora envie os detalhes de pagamento de volta. Nesse caso, você está enviando apenas o total da solicitação de pagamento, mas pode enviar mais detalhes, se quiser.
[payment handler] service-worker.js:
…
// Pass the payment details to the frontend
postMessage('PAYMENT_IS_READY', { total });
break;
…
[payment handler] frontend:
let total;
navigator.serviceWorker.addEventListener('message', async e => {
switch (e.data.type) {
case 'PAYMENT_IS_READY':
({ total } = e.data);
// Update the UI
renderHTML(total);
break;
…
Retornar as credenciais de pagamento do cliente
Quando o cliente autoriza o pagamento, o front-end pode enviar uma mensagem de postagem
para o worker de serviço para continuar. É possível resolver a promessa transmitida para
PaymentRequestEvent.respondWith()
para enviar o resultado de volta ao comerciante.
Transmita um
objeto
PaymentHandlerResponse
.
Nome da propriedade | Descrição |
---|---|
methodName |
O identificador da forma de pagamento usada para fazer o pagamento. |
details |
Os dados específicos da forma de pagamento que fornecem as informações necessárias para o comerciante processar o pagamento. |
[payment handler] frontend:
const paymentMethod = …
postMessage('PAYMENT_AUTHORIZED', {
paymentMethod, // Payment method identifier
});
[payment handler] service-worker.js:
…
// Received a message from the frontend
self.addEventListener('message', async e => {
let details;
try {
switch (e.data.type) {
…
case 'PAYMENT_AUTHORIZED':
// Resolve the payment request event promise
// with a payment response object
const response = {
methodName: e.data.paymentMethod,
details: { id: 'put payment credential here' },
}
resolver.resolve(response);
// Don't forget to initialize.
payment_request_event = null;
break;
…
Cancelar a transação de pagamento
Para permitir que o cliente cancele a transação, o front-end pode enviar uma mensagem de postagem
para o worker de serviço. O worker de serviço pode resolver a
promessa transmitida para PaymentRequestEvent.respondWith()
com null
para indicar ao
merchant que a transação foi cancelada.
[payment handler] frontend:
postMessage('CANCEL_PAYMENT');
[payment handler] service-worker.js:
…
// Received a message from the frontend
self.addEventListener('message', async e => {
let details;
try {
switch (e.data.type) {
…
case 'CANCEL_PAYMENT':
// Resolve the payment request event promise
// with null
resolver.resolve(null);
// Don't forget to initialize.
payment_request_event = null;
break;
…
Código de amostra
Todos os códigos de exemplo que você viu neste documento foram trechos do seguinte app de exemplo funcional:
https://paymenthandler-demo.glitch.me
[payment handler] service worker
[payment handler] frontend
Para testar:
- Acesse https://paymentrequest-demo.glitch.me/.
- Acesse a parte inferior da página.
- Clique no botão Adicionar uma forma de pagamento.
- Insira
https://paymenthandler-demo.glitch.me
no campo Identificador da forma de pagamento. - Pressione o botão Pagar ao lado do campo.
Próximas etapas
Neste artigo, aprendemos a orquestrar uma transação de pagamento de um service worker. A próxima etapa é aprender a adicionar alguns recursos mais avançados ao service worker.