- Compatibilidade com XF
- 2.3.x
- Descrição curta
- This add-on provides advanced refund capabilities for XenForo, including admin-initiated refunds and smart partial refund handling. It integrates seamlessly with Stripe and PayPal, offering a robust framework for payment providers and add-ons to manage refunds efficiently. Users can initiate refunds directly from the admin panel or via purchase logs, ensuring smooth user upgrades and seamless transaction management.
Admin navega para Logs → Pagador →[specific=payment entry]Clique em "Reembolso" (apenas visível para fornecedores que suportam reembolsos)
Insira o valor do reembolso (preenchido automaticamente com o saldo restante de reembolso possível)
Para atualizações de usuários: opção de desfazer a compra (rebaixar nível do usuário)
Para outros tipos de compras: o reembolso é processado pelo fornecedor e o adicional proprietário trata a reversão via o evento payment_refund_complete
O adicional chama o API de reembolso do fornecedor, registra o resultado e rastreia o valor total reembolsado
Inicie uma compra do fornecedor: logue
Se a compra foi feita para uma Upgrada de Usuário gerenciada pelo XenForo, você pode especificar o valor do reembolso e a ação desejada para a upgrade.
Se a compra foi feita em outro adicional, você será solicitado a gerar apenas um reembolso:
Adiciona supportsRefunds() à sua provedora
No seu classe de provedor (que herda XF\Payment\AbstractProvider), adicione:
supportsRefunds(): bool {}
Passos 2: Implementar método devolução() com essa assinatura exata:
Reembolsar
Você também precisará registrar este ouvinte em seu arquivo _data/code_event_listeners.xml do seu addon:
Notas importantes
Não é necessário dependência: Não use ou requer quaisquer classes do namespace Jack\PaymentRefund. Seu provedor deve ter zero referências ao adendo de reembolso.
Resolução da ID de transação: O parâmetro $transactionId vem da coluna transaction_id da entrada xf_payment_provider_log que o administrador está reembolsando. Dependendo do como seu provedor registra pagamentos, isso pode ou não ser a ID que você precisa para sua API de reembolso. Se não for, procure a ID correta na log_entry log_details ou provider_metadata da requisição de compra. Veja o método resolveChargeId() no extensão Stripe como exemplo.
Gerenciamento de moeda: O $amount sempre é um valor decimal (por exemplo, 10.00). Se a API do seu provedor espera valores em unidade monetária mínima (como centavos), converta-o na sua método refund().
Reembolsos parciais: O adendo de reembolso gerencia automaticamente o rastreamento acumulado. Sua método refund() só precisa processar qualquer valor que lhe seja dado. O adendo garante que $amount nunca exceda o saldo restante refazível.
Dedução de webhook: Quando um administrador emite um reembolso, a subsequente webhook do provedor (por exemplo, o refunded da Stripe) é detectada como duplicata e registrada informativamente — evitando dobrados reversos.
Insira o valor do reembolso (preenchido automaticamente com o saldo restante de reembolso possível)
Para atualizações de usuários: opção de desfazer a compra (rebaixar nível do usuário)
Para outros tipos de compras: o reembolso é processado pelo fornecedor e o adicional proprietário trata a reversão via o evento payment_refund_complete
O adicional chama o API de reembolso do fornecedor, registra o resultado e rastreia o valor total reembolsado
Inicie uma compra do fornecedor: logue
Se a compra foi feita para uma Upgrada de Usuário gerenciada pelo XenForo, você pode especificar o valor do reembolso e a ação desejada para a upgrade.
Se a compra foi feita em outro adicional, você será solicitado a gerar apenas um reembolso:
Adiciona supportsRefunds() à sua provedora
No seu classe de provedor (que herda XF\Payment\AbstractProvider), adicione:
supportsRefunds(): bool {}
PHP:
public function supportsRefunds(): bool
{
return true;
}
PHP:
public function refund(
\XF\Entity\PaymentProfile $paymentProfile,
\XF\Entity\PurchaseRequest $purchaseRequest,
string $transactionId,
?float $amount = null,
string $currency = 'USD'
): array
{
// $paymentProfile - contains your API credentials in $paymentProfile->options
// $purchaseRequest - the original purchase (has cost_amount, cost_currency, provider_metadata)
// $transactionId - the transaction ID from the payment log entry being refunded
// $amount - refund amount (null means full refund)
// $currency - currency code
// Call your provider's refund API here...
// On success, return:
return [
'success' => true,
'provider_refund_id' => 'your_provider_refund_id',
];
// On failure, return:
return [
'success' => false,
'error' => 'Human-readable error message',
];
}
PHP:
public static function onPaymentRefundComplete(
\XF\Entity\PaymentProviderLog &$logEntry,
\XF\Entity\PurchaseRequest &$purchaseRequest,
float $amount,
string $currency,
bool $purchaseReversed,
array $providerResult
): void
{
// Check if this refund is for your purchasable type
if ($purchaseRequest->purchasable_type_id !== 'your_purchasable_type')
{
return;
}
// Handle the refund (e.g., revoke access, send notification)
}
XML:
<listeners>
<listener event_id="payment_refund_complete"
execute_order="10"
callback_class="Your\AddOn\Listener"
callback_method="onPaymentRefundComplete"
active="1" />
</listeners>
Não é necessário dependência: Não use ou requer quaisquer classes do namespace Jack\PaymentRefund. Seu provedor deve ter zero referências ao adendo de reembolso.
Resolução da ID de transação: O parâmetro $transactionId vem da coluna transaction_id da entrada xf_payment_provider_log que o administrador está reembolsando. Dependendo do como seu provedor registra pagamentos, isso pode ou não ser a ID que você precisa para sua API de reembolso. Se não for, procure a ID correta na log_entry log_details ou provider_metadata da requisição de compra. Veja o método resolveChargeId() no extensão Stripe como exemplo.
Gerenciamento de moeda: O $amount sempre é um valor decimal (por exemplo, 10.00). Se a API do seu provedor espera valores em unidade monetária mínima (como centavos), converta-o na sua método refund().
Reembolsos parciais: O adendo de reembolso gerencia automaticamente o rastreamento acumulado. Sua método refund() só precisa processar qualquer valor que lhe seja dado. O adendo garante que $amount nunca exceda o saldo restante refazível.
Dedução de webhook: Quando um administrador emite um reembolso, a subsequente webhook do provedor (por exemplo, o refunded da Stripe) é detectada como duplicata e registrada informativamente — evitando dobrados reversos.