{"id":39648,"date":"2025-07-09T11:47:31","date_gmt":"2025-07-09T18:47:31","guid":{"rendered":"https:\/\/nuvix.com\/?page_id=39648"},"modified":"2025-09-06T16:55:56","modified_gmt":"2025-09-06T23:55:56","slug":"payment-page-new","status":"publish","type":"page","link":"https:\/\/nuvix.com\/pt\/payment-page-new\/","title":{"rendered":"payment-page-new"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"39648\" class=\"elementor elementor-39648\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-79bcf65 e-flex e-con-boxed e-con e-parent\" data-id=\"79bcf65\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-640c52b elementor-widget elementor-widget-shortcode\" data-id=\"640c52b\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><style>\n  .payment-container {\n    max-width: 400px;\n    margin: 3rem auto;\n    background: #fff;\n    border-radius: 16px;\n    box-shadow: 0 8px 24px rgba(0,0,0,0.1);\n    overflow: hidden;\n    text-align: center;\n    position: relative;\n  }\n  .payment-container::before {\n    content: '';\n    position: absolute;\n    top: 0; left: 0;\n    width: 100%; height: 6px;\n    background: linear-gradient(90deg, #6A11CB, #2575FC);\n  }\n  .checkout-logo {\n    display: block;\n    width: 140px;\n    max-width: 60%;\n    margin: 1.5rem auto;\n  }\n  #payment-element {\n    margin: 0 1rem 1.5rem;\n    padding: 1.2rem;\n    border-radius: 12px;\n    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.1);\n  }\n  #submit {\n    display: inline-block;\n    width: calc(100% - 2rem);\n    margin: 0 1rem 0.75rem;\n    padding: 1rem 0;\n    font-size: 1rem;\n    font-weight: 700;\n    text-transform: uppercase;\n    background: linear-gradient(90deg, #6A11CB, #2575FC);\n    border: none;\n    border-radius: 999px;\n    color: #fff;\n    cursor: pointer;\n    transition: transform 0.15s ease, box-shadow 0.15s ease;\n  }\n  #submit:hover:not(:disabled) {\n    transform: translateY(-2px);\n    box-shadow: 0 6px 12px rgba(0,0,0,0.12);\n  }\n  #submit:disabled {\n    opacity: 0.6;\n    cursor: not-allowed;\n    transform: none;\n    box-shadow: none;\n  }\n  #back-button {\n    display: inline-block;\n    width: calc(100% - 2rem);\n    margin: 0 1rem 1.5rem;\n    padding: 0.75rem 0;\n    font-size: 0.9rem;\n    font-weight: 600;\n    background: #f2f2f2;\n    border: none;\n    border-radius: 999px;\n    color: #333;\n    cursor: pointer;\n    transition: background 0.2s;\n  }\n  #back-button:hover {\n    background: #e0e0e0;\n  }\n  #payment-message {\n    margin: 0 1rem 1.5rem;\n    font-size: 0.9rem;\n    color: #e53e3e;\n    min-height: 1.2rem;\n  }\n  #payment-message.success {\n    color: #48bb78;\n  }\n  .security-badge {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 0.5rem;\n    margin: 0 1rem 1.5rem;\n    font-size: 0.85rem;\n    color: #666;\n  }\n  .security-badge svg {\n    width: 16px;\n    height: 16px;\n    fill: #48bb78;\n  }\n  \/* Spinner *\/\n  .spinner {\n    display: inline-block;\n    width: 14px;\n    height: 14px;\n    border: 2px solid #fff;\n    border-radius: 50%;\n    border-top-color: transparent;\n    animation: spin 0.8s linear infinite;\n    margin-right: 8px;\n    vertical-align: middle;\n  }\n  @keyframes spin {\n    to { transform: rotate(360deg); }\n  }\n  \/* Mobile optimizations *\/\n  @media (max-width: 480px) {\n    .payment-container {\n      margin: 1rem;\n      border-radius: 12px;\n    }\n    #submit {\n      font-size: 1.1rem;\n      padding: 1.2rem 0;\n    }\n  }\n  \/* RTL support for Arabic *\/\n  <\/style>\n\n<div class=\"payment-container\">\n  <img decoding=\"async\" src=\"https:\/\/nuvix.com\/wp-content\/uploads\/2025\/07\/cropped-cropped-2-2-1.png\"\n       alt=\"Nuvix Logo\"\n       class=\"checkout-logo\" \/>\n\n  <form id=\"checkout-form\" action=\"\">\n    <div id=\"payment-element\"><\/div>\n    <button id=\"submit\">Loading\u2026<\/button>\n    <button type=\"button\" id=\"back-button\">Back to Checkout<\/button>\n    <div id=\"payment-message\" role=\"alert\" aria-live=\"polite\"><\/div>\n    <div class=\"security-badge\">\n      <svg viewbox=\"0 0 24 24\">\n        <path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4z\"\/>\n      <\/svg>\n      <span>Secure payment<\/span>\n    <\/div>\n  <input type=\"hidden\" name=\"trp-form-language\" value=\"pt\"\/><\/form>\n<\/div>\n\n<script src=\"https:\/\/js.stripe.com\/v3\"><\/script>\n<script>\ndocument.addEventListener('DOMContentLoaded', async () => {\n  \/\/ Translations\n  const translations = {\"loading\":\"Loading\\u2026\",\"pay\":\"Pay\",\"back_to_checkout\":\"Back to Checkout\",\"missing_params\":\"Missing client_secret or thankpage parameters.\",\"processing\":\"Processing...\",\"payment_successful\":\"Payment successful! Redirecting...\",\"payment_failed\":\"Payment could not be confirmed. Please try again.\",\"secure_payment\":\"Secure payment\",\"card_declined\":\"Your card was declined. Please try a different payment method.\",\"insufficient_funds\":\"Your card has insufficient funds.\",\"expired_card\":\"Your card has expired. Please use a different card.\",\"incorrect_cvc\":\"Your card's security code is incorrect.\",\"processing_error\":\"An error occurred while processing your card. Please try again.\",\"network_error\":\"Connection error. Please check your internet and try again.\",\"generic_error\":\"An unexpected error occurred. Please try again.\"};\n  const stripeLocale = 'pt';\n  const currentLang = 'pt';\n  \n  const params       = new URLSearchParams(window.location.search);\n  const clientSecret = params.get('client_secret');\n  const thankPage    = params.get('thankpage');\n  const btn          = document.getElementById('submit');\n  const backBtn      = document.getElementById('back-button');\n  const msgEl        = document.getElementById('payment-message');\n\n  \/\/ Back to checkout with language support\n  backBtn.addEventListener('click', () => {\n    let checkoutUrl = 'https:\/\/nuvix.com\/checkout';\n    \/\/ Preserve language in URL\n    if (currentLang !== 'en') {\n      checkoutUrl = checkoutUrl.replace('\/checkout', `\/${currentLang}\/checkout`);\n    }\n    window.location.href = checkoutUrl;\n  });\n\n  if (!clientSecret || !thankPage) {\n    msgEl.textContent = translations.missing_params;\n    btn.disabled = true;\n    backBtn.disabled = true;\n    return;\n  }\n\n  const stripe = Stripe('pk_live_toarlatNd0x4Gj5unV6jEZ3U004cEzxmVX', { locale: stripeLocale });\n\n  \/\/ Show amount on button with proper currency formatting\n  const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);\n  if (paymentIntent) {\n    const amt = (paymentIntent.amount \/ 100).toFixed(2);\n    const cur = paymentIntent.currency.toUpperCase();\n    \n    \/\/ Format currency based on language\n    let formattedAmount;\n    switch(currentLang) {\n      case 'es':\n      case 'fr':\n      case 'it':\n      case 'pt':\n        formattedAmount = `${amt.replace('.', ',')} ${cur}`;\n        break;\n      case 'de':\n        formattedAmount = `${amt.replace('.', ',')} ${cur}`;\n        break;\n      case 'ja':\n        formattedAmount = `\u00a5${Math.round(paymentIntent.amount \/ 100)}`;\n        break;\n      case 'zh':\n        formattedAmount = `\u00a5${amt}`;\n        break;\n      default:\n        formattedAmount = `$${amt} ${cur}`;\n    }\n    \n    btn.textContent = `${translations.pay} ${formattedAmount}`;\n    btn.setAttribute('aria-label', `${translations.pay} ${formattedAmount}`);\n  }\n\n  const elements = stripe.elements({ clientSecret, locale: stripeLocale });\n  elements.create('payment').mount('#payment-element');\n\n  \/\/ Enhanced error handling with translations\n  const getErrorMessage = (error) => {\n    const errorMessages = {\n      'card_declined': translations.card_declined,\n      'insufficient_funds': translations.insufficient_funds,\n      'expired_card': translations.expired_card,\n      'incorrect_cvc': translations.incorrect_cvc,\n      'processing_error': translations.processing_error,\n      'network_error': translations.network_error\n    };\n    return errorMessages[error.code] || error.message || translations.generic_error;\n  };\n\n  \/\/ Show success message\n  const showSuccess = () => {\n    msgEl.classList.add('success');\n    msgEl.innerHTML = `\u2713 ${translations.payment_successful}`;\n  };\n\n  \/\/ Show error message\n  const showError = (message) => {\n    msgEl.classList.remove('success');\n    msgEl.textContent = message;\n  };\n\n  async function waitForSuccess(secret, interval = 2000, timeout = 30000) {\n    const start = Date.now();\n    while (Date.now() - start < timeout) {\n      const { paymentIntent: pi } = await stripe.retrievePaymentIntent(secret);\n      if (pi.status === 'succeeded') return true;\n      if (['requires_payment_method','canceled'].includes(pi.status)) break;\n      await new Promise(r => setTimeout(r, interval));\n    }\n    return false;\n  }\n\n  document.getElementById('checkout-form').addEventListener('submit', async e => {\n    e.preventDefault();\n    btn.disabled = true;\n    btn.setAttribute('aria-busy', 'true');\n    btn.innerHTML = `<span class=\"spinner\"><\/span> ${translations.processing}`;\n    msgEl.textContent = '';\n\n    try {\n      const { error, paymentIntent: pi } = await stripe.confirmPayment({\n        elements,\n        confirmParams: { return_url: window.location.href },\n        redirect: 'if_required'\n      });\n\n      if (error) {\n        showError(getErrorMessage(error));\n        btn.disabled = false;\n        btn.setAttribute('aria-busy', 'false');\n        btn.textContent = btn.getAttribute('data-original-text') || translations.pay;\n        return;\n      }\n\n      if (pi.status === 'succeeded') {\n        showSuccess();\n        setTimeout(() => {\n          window.location.href = thankPage;\n        }, 1000);\n        return;\n      }\n\n      if (pi.status === 'requires_action') {\n        const { error: nextError } = await stripe.handleNextAction(pi.client_secret);\n        if (nextError) {\n          showError(getErrorMessage(nextError));\n          btn.disabled = false;\n          btn.setAttribute('aria-busy', 'false');\n          btn.textContent = btn.getAttribute('data-original-text') || translations.pay;\n          return;\n        }\n        const { paymentIntent: finalPI } = await stripe.retrievePaymentIntent(pi.client_secret);\n        if (finalPI.status === 'succeeded') {\n          showSuccess();\n          setTimeout(() => {\n            window.location.href = thankPage;\n          }, 1000);\n          return;\n        }\n      }\n\n      if (await waitForSuccess(pi.client_secret)) {\n        showSuccess();\n        setTimeout(() => {\n          window.location.href = thankPage;\n        }, 1000);\n      } else {\n        showError(translations.payment_failed);\n        btn.disabled = false;\n        btn.setAttribute('aria-busy', 'false');\n        btn.textContent = btn.getAttribute('data-original-text') || translations.pay;\n      }\n    } catch (err) {\n      showError(translations.generic_error);\n      btn.disabled = false;\n      btn.setAttribute('aria-busy', 'false');\n      btn.textContent = btn.getAttribute('data-original-text') || translations.pay;\n    }\n  });\n\n  \/\/ Save original button text\n  btn.setAttribute('data-original-text', btn.textContent);\n});\n<\/script>\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-39648","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/pages\/39648","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/comments?post=39648"}],"version-history":[{"count":22,"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/pages\/39648\/revisions"}],"predecessor-version":[{"id":45031,"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/pages\/39648\/revisions\/45031"}],"wp:attachment":[{"href":"https:\/\/nuvix.com\/pt\/wp-json\/wp\/v2\/media?parent=39648"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}