fix(helcim): skip HelcimPay verify when a card is already on file
Helcim refuses paymentType:'verify' for cards already saved on a
customer ("A new card must be entered for saving the payment method"),
breaking every "Complete Payment" retry after a partial-failed signup.
Add GET /api/helcim/existing-card and short-circuit HelcimPay verify in
useMemberPayment + payment-setup.vue when a saved card is found, going
straight to subscription creation. The two existence-check fetches run
in parallel with get-or-create-customer so no extra round-trip latency
in the common path.
This commit is contained in:
parent
e3410c52a5
commit
0f841912e2
4 changed files with 201 additions and 42 deletions
|
|
@ -25,45 +25,53 @@ export const useMemberPayment = () => {
|
|||
paymentSuccess.value = false
|
||||
|
||||
try {
|
||||
// Step 1: Get or create Helcim customer
|
||||
await getOrCreateCustomer()
|
||||
// Skip HelcimPay verify if a card's already on file — Helcim refuses
|
||||
// to re-save it, breaking retries after a partial-failed signup.
|
||||
const [, existing] = await Promise.all([
|
||||
getOrCreateCustomer(),
|
||||
$fetch('/api/helcim/existing-card').catch((err) => {
|
||||
console.warn('[payment] existing-card lookup failed, falling back to verify flow:', err)
|
||||
return null
|
||||
}),
|
||||
])
|
||||
|
||||
// Step 2: Initialize Helcim payment with $0 for card verification
|
||||
await initializeHelcimPay(
|
||||
customerId.value,
|
||||
customerCode.value,
|
||||
0,
|
||||
)
|
||||
let cardToken = existing?.cardToken || null
|
||||
|
||||
// Step 3: Show payment modal and get payment result
|
||||
const paymentResult = await verifyPayment()
|
||||
console.log('Payment result:', paymentResult)
|
||||
if (!cardToken) {
|
||||
await initializeHelcimPay(
|
||||
customerId.value,
|
||||
customerCode.value,
|
||||
0,
|
||||
)
|
||||
|
||||
if (!paymentResult.success) {
|
||||
throw new Error('Payment verification failed')
|
||||
const paymentResult = await verifyPayment()
|
||||
|
||||
if (!paymentResult.success) {
|
||||
throw new Error('Payment verification failed')
|
||||
}
|
||||
|
||||
const verifyResult = await $fetch('/api/helcim/verify-payment', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
cardToken: paymentResult.cardToken,
|
||||
customerId: customerId.value,
|
||||
},
|
||||
})
|
||||
|
||||
if (!verifyResult.success) {
|
||||
throw new Error('Payment verification failed on backend')
|
||||
}
|
||||
|
||||
cardToken = paymentResult.cardToken
|
||||
}
|
||||
|
||||
// Step 4: Verify payment on backend
|
||||
const verifyResult = await $fetch('/api/helcim/verify-payment', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
cardToken: paymentResult.cardToken,
|
||||
customerId: customerId.value,
|
||||
},
|
||||
})
|
||||
|
||||
if (!verifyResult.success) {
|
||||
throw new Error('Payment verification failed on backend')
|
||||
}
|
||||
|
||||
// Step 5: Create subscription with proper contribution tier
|
||||
const subscriptionResponse = await $fetch('/api/helcim/subscription', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
customerId: customerId.value,
|
||||
customerCode: customerCode.value,
|
||||
contributionAmount: memberData.value?.contributionAmount ?? 5,
|
||||
cardToken: paymentResult.cardToken,
|
||||
cardToken,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -71,7 +79,6 @@ export const useMemberPayment = () => {
|
|||
throw new Error('Subscription creation failed')
|
||||
}
|
||||
|
||||
// Step 6: Payment successful - refresh member data
|
||||
paymentSuccess.value = true
|
||||
await checkMemberStatus()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue