Integrar sistemas de pagamento em aplicações Ionic pode parecer simples, mas esconde desafios inesperados. Abaixo, detalho a implementação prática do Alipay e do WeChat Pay, incluindo as armadilhas mais comuns.
1. Alipay
Após testar diversos plugins Cordova, o que se mostrou mais estável foi o cordova-plugin-alipay-v2. Ele utiliza o SDK mais recente e evita erros de compatibilidade.
Instalação:
ionic cordova plugin add cordova-plugin-alipay-v2 --variable APP_ID=seu_app_id_aqui
Menu de seleção de pagamento:
openPaymentSheet(data) {
this.actionSheetCtrl.create({
buttons: [
{
text: "Alipay",
handler: () => this.alipayPayment(data)
},
{
text: "WeChat Pay",
handler: () => this.wechatPayment(data)
},
{
text: "Cancelar",
role: 'cancel'
}
]
}).present();
}
Chamada ao backend e tratamento da string de assinatura:
O backend deve gerar a string de assinatura conforme a documentação oficial do Alipay. Um problema comum é que caracteres especiais como & vêm escapados (ex: &), impedindo que o SDK móvel processe corretamente. A solução é desescapar a string entes de passá-la ao plugin.
decodeHtmlEntities(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, "'");
}
alipayPayment(orderId) {
this.http.post('https://api.exemplo.com/pay/alipay', { order_id: orderId })
.subscribe(response => {
const cleanSignature = this.decodeHtmlEntities(response.signature);
cordova.plugins.alipay.payment(cleanSignature,
success => {
if (success.resultStatus === "9000") {
this.handlePaymentSuccess(orderId);
} else {
this.handlePaymentFailure();
}
},
error => this.handlePaymentFailure()
);
});
}
Após o pagamento bem-sucedido, o backend deve confirmar a transação e atualizar o status do pedido.
2. WeChat Pay
Para o WeChat Pay, utilize o plugin cordova-plugin-wechat, que também suporta funcionalidades como compartilhamento.
Instalação:
ionic cordova plugin add cordova-plugin-wechat --variable wechatappid=seu_app_id
Wrapper TypeScript para o plugin:
declare var Wechat: any;
interface PaymentParams {
partnerid: string;
prepayid: string;
noncestr: string;
timestamp: string;
sign: string;
}
class WechatService {
static isWechatInstalled(): Promise<boolean> {
return new Promise((resolve, reject) => {
Wechat.isInstalled(
result => resolve(result),
error => reject(error)
);
});
}
static sendPayment(params: PaymentParams): Promise<any> {
return new Promise((resolve, reject) => {
Wechat.sendPaymentRequest(params,
result => resolve(result),
error => reject(error)
);
});
}
}
Processo de pagamento:
wechatPayment(orderId: string) {
this.http.post('https://api.exemplo.com/pay/wechat', { order_id: orderId })
.subscribe(response => {
const paymentData = {
partnerid: response.partnerid,
prepayid: response.prepayid,
noncestr: response.noncestr,
timestamp: String(response.timestamp), // Importante: converter para string
sign: response.sign
};
WechatService.sendPayment(paymentData)
.then(() => this.handlePaymentSuccess(orderId))
.catch(() => this.handlePaymentFailure());
});
}
Pontos críticos:
- O campo
timestampdeve ser uma string. Backends geralmente o retornam como número, então a conversão é obrigatória. - O WeChat exige que cada transação tenha um ID único. Se um pedido for cancelado e tentar ser pago novamente, a segunda tentativa falhará. O backend deve gerar um novo
prepayida cada tentativa.