payment fix

This commit is contained in:
elvira
2026-09-15 19:20:59 +03:00
parent 1598f053ee
commit ba6d68c5b9
5 changed files with 155 additions and 96 deletions
@@ -30,6 +30,7 @@ export default class extends Controller {
this.saveTimer = null
this.saveController = null
this.statusTimer = null
this.shippingPromise = null
if (this.hasSameAsBillingTarget) this.applySameAsBilling()
}
@@ -108,6 +109,9 @@ export default class extends Controller {
async flush() {
clearTimeout(this.saveTimer)
await this.save()
// A shipping-method radio click fires its own (undebounced) request —
// still async, still racy against an immediate "place order" click.
if (this.shippingPromise) await this.shippingPromise
}
async save() {
@@ -137,11 +141,18 @@ export default class extends Controller {
}
async selectShipping(event) {
// Tracked so flush() can await it — nothing else stops "place order"
// (a separate, unrelated click) from racing ahead of this request.
this.shippingPromise = this.doSelectShipping(event.target.value)
await this.shippingPromise
}
async doSelectShipping(value) {
this.saveController?.abort()
this.setStatus('saving')
const body = new FormData()
body.append('shipping_option', event.target.value)
body.append('shipping_option', value)
try {
const response = await fetch(this.selectShippingUrlValue, {
@@ -160,6 +171,8 @@ export default class extends Controller {
this.setStatus('saved')
} catch {
this.setStatus('error')
} finally {
this.shippingPromise = null
}
}
@@ -215,6 +215,15 @@ export default class extends Controller {
return
}
// Points at the section that actually needs attention, rather than
// leaving a generic error and making the shopper hunt for it — e.g. a
// region with 2+ shipping methods needs an explicit pick, easy to miss.
if (data.field === 'shipping_option') {
document.getElementById('bbk-shipping-options')?.scrollIntoView({ block: 'center', behavior: 'smooth' })
this.fail(data.message || data.error || this.genericErrorValue, { scroll: false })
return
}
this.fail(data.message || data.error || this.genericErrorValue)
}
@@ -252,15 +261,15 @@ export default class extends Controller {
// ── helpers ──────────────────────────────────────────────────────
fail(message) {
this.showError(message)
fail(message, { scroll = true } = {}) {
this.showError(message, { scroll })
this.submitTarget.disabled = false
}
showError(message) {
showError(message, { scroll = true } = {}) {
this.errorTarget.textContent = message
this.errorTarget.hidden = false
this.errorTarget.scrollIntoView({ block: 'center', behavior: 'smooth' })
if (scroll) this.errorTarget.scrollIntoView({ block: 'center', behavior: 'smooth' })
}
clearError() {