Merge pull request #4907 from expsa/reverse_pci

Reverse pci
This commit is contained in:
abdurrahman-saber 2025-10-14 18:23:27 +03:00 committed by GitHub
commit 03065ac17d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 20 additions and 53 deletions

View File

@ -1,30 +1,21 @@
import json import json
import secrets
import requests
from odoo.http import route, request, Controller from odoo.http import route, request, Controller
class ApplePayFastCheckout(Controller): class ApplePayFastCheckout(Controller):
@route('/applepay', type='http', auth='public', website=True, csrf=False) @route('/applepay', type='http', auth='public', website=True, csrf=False)
def apple_pay_iframe(self, **kwargs): def apple_pay_iframe(self, **kwargs):
nonce = secrets.token_urlsafe(16)
acquirer_id = request.env['payment.acquirer'].sudo().search([('provider', '=', 'applepay')], limit=1) acquirer_id = request.env['payment.acquirer'].sudo().search([('provider', '=', 'applepay')], limit=1)
if acquirer_id.state == 'test': if acquirer_id.state == 'test':
url = "https://eu-test.oppwa.com" url = "https://eu-test.oppwa.com/v1/paymentWidgets.js"
else: else:
url = "https://eu-prod.oppwa.com" url = "https://oppwa.com/v1/paymentWidgets.js"
integrity = requests.get(f'{url}/v1/fastcheckout/integrity').json().get('integrity', '') response = request.render("applepay_fast_checkout.apple_pay_iframe", {'hyperpay_src': url, 'merchant_id': acquirer_id.applepay_entity_id})
response.headers['Content-Security-Policy'] = "script-src blob: 'self' 'unsafe-inline' 'unsafe-eval' https://*; worker-src blob: 'self' 'unsafe-inline' 'unsafe-eval' https://*;connect-src 'self' https://* wss://*;frame-src 'self' blob: https://*;"
response = request.render("applepay_fast_checkout.apple_pay_iframe", {
'hyperpay_src': f"{url}/v1/paymentWidgets.js",
'merchant_id': acquirer_id.applepay_entity_id,
'script_nonce': nonce,
'integrity': integrity
})
# response.headers['Content-Security-Policy'] = "script-src blob: 'self' 'unsafe-inline' 'unsafe-eval' https://*; worker-src blob: 'self' 'unsafe-inline' 'unsafe-eval' https://*;connect-src 'self' https://* wss://*;frame-src 'self' blob: https://*;"
return response return response

View File

@ -4,20 +4,12 @@
<template id="apple_pay_iframe" name="Apple Pay Iframe"> <template id="apple_pay_iframe" name="Apple Pay Iframe">
<html> <html>
<head> <head>
<meta http-equiv="Content-Security-Policy" <script t-att-src="hyperpay_src" />
t-attf-content=" <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js" />
style-src 'self' https://*.oppwa.com 'unsafe-inline'; <script>
frame-src 'self' https://*.oppwa.com https://applepay.cdn-apple.com;
script-src 'self' https://*.oppwa.com https://applepay.cdn-apple.com 'nonce-{{script_nonce}}';
connect-src 'self' https://*.oppwa.com;
img-src 'self' https://*.oppwa.com;" />
<script t-att-src="hyperpay_src" t-att-integrity="integrity" crossorigin="anonymous" />
<script src="/web/static/lib/jquery/jquery.js" t-att-nonce="script_nonce" />
<script t-att-nonce="script_nonce">
merchant_id = "<t t-esc="merchant_id" />"; merchant_id = "<t t-esc="merchant_id" />";
</script> </script>
<script src="/applepay_fast_checkout/static/src/js/applepay_iframe.js" t-att-nonce="script_nonce"/> <script src="/applepay_fast_checkout/static/src/js/applepay_iframe.js" />
<link rel="stylesheet" href="/applepay_fast_checkout/static/src/css/applepay_iframe_content.css" /> <link rel="stylesheet" href="/applepay_fast_checkout/static/src/css/applepay_iframe_content.css" />
</head> </head>
<body> <body>

View File

@ -6,10 +6,8 @@
################################################################################# #################################################################################
import requests import requests
import random
import secrets
from odoo import http from odoo import http
import random
from odoo.http import request from odoo.http import request
from odoo.addons.payment_hyperpay.data.payment_icon import payment_icon from odoo.addons.payment_hyperpay.data.payment_icon import payment_icon
@ -17,7 +15,8 @@ from odoo.addons.payment_hyperpay.data.payment_icon import payment_icon
import logging import logging
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
# test_domain = "https://test.oppwa.com"
# live_domain = "https://oppwa.com"
test_domain = "https://eu-test.oppwa.com" test_domain = "https://eu-test.oppwa.com"
live_domain = "https://eu-prod.oppwa.com" live_domain = "https://eu-prod.oppwa.com"
@ -47,7 +46,6 @@ class HyperPayController(http.Controller):
@http.route('/payment/hyperpay/checkout/create', type='json', auth='public', csrf=False, website=True) @http.route('/payment/hyperpay/checkout/create', type='json', auth='public', csrf=False, website=True)
def create_hyperpay_checkout(self, **post): def create_hyperpay_checkout(self, **post):
_logger.info('--post---%r', post) _logger.info('--post---%r', post)
nonce = secrets.token_urlsafe(16)
tx = request.env['payment.transaction'].sudo().search([('id', '=', int(post.get('txId', 0)))]) tx = request.env['payment.transaction'].sudo().search([('id', '=', int(post.get('txId', 0)))])
final_response = {} final_response = {}
if tx: if tx:
@ -67,7 +65,6 @@ class HyperPayController(http.Controller):
"currency": tx.currency_id and tx.sudo().currency_id.name or '', "currency": tx.currency_id and tx.sudo().currency_id.name or '',
"paymentType": "DB", "paymentType": "DB",
"env": acq.state, "env": acq.state,
"integrity": "true",
"customParameters[SHOPPER_tx_id]": tx.id, "customParameters[SHOPPER_tx_id]": tx.id,
"merchantTransactionId": tx.reference, "merchantTransactionId": tx.reference,
"billing.street1": partner_id.street or 'Riyadh', "billing.street1": partner_id.street or 'Riyadh',
@ -98,9 +95,7 @@ class HyperPayController(http.Controller):
'base_url': base_url, 'base_url': base_url,
'data_brands': data_brands, 'data_brands': data_brands,
'acq': acq.id, 'acq': acq.id,
'website_id': request.session.get('force_website_id') or request.website.id, 'website_id': request.session.get('force_website_id') or request.website.id
'integrity': resp.get('integrity', ''),
'nonce': nonce,
} }
return final_response return final_response

View File

@ -16,7 +16,7 @@ odoo.define("payment_hyperpay.payment_hyperpay", function (require) {
// Reference // Reference
// https://dev.to/pulljosh/how-to-load-html-css-and-js-code-into-an-iframe-2blc // https://dev.to/pulljosh/how-to-load-html-css-and-js-code-into-an-iframe-2blc
const getGeneratedPageURL = ({ html, css, js, meta, nonce}) => { const getGeneratedPageURL = ({ html, css, js }) => {
const getBlobURL = (code, type) => { const getBlobURL = (code, type) => {
const blob = new Blob([code], { type }); const blob = new Blob([code], { type });
return URL.createObjectURL(blob); return URL.createObjectURL(blob);
@ -25,12 +25,11 @@ odoo.define("payment_hyperpay.payment_hyperpay", function (require) {
const source = ` const source = `
<html> <html>
<head> <head>
${meta}
${css} ${css}
${js} ${js}
</head> </head>
<body> <body>
<script nonce="${nonce}"> <script>
var wpwlOptions = { var wpwlOptions = {
onReady: function(){ onReady: function(){
var shopOrigin = $('input[name="shopOrigin"]'); var shopOrigin = $('input[name="shopOrigin"]');
@ -67,7 +66,7 @@ odoo.define("payment_hyperpay.payment_hyperpay", function (require) {
} }
} }
</script> </script>
<script nonce="${nonce}"> <script>
var wpwlOptions = { var wpwlOptions = {
browser: {threeDChallengeWindow: 5 }, browser: {threeDChallengeWindow: 5 },
locale: "ar", locale: "ar",
@ -104,20 +103,20 @@ odoo.define("payment_hyperpay.payment_hyperpay", function (require) {
txId: self.tx_id, txId: self.tx_id,
}).then(function (result) { }).then(function (result) {
if (result) { if (result) {
self._renderHyperpayModal(result.checkoutId, result.domain, result.base_url, result.data_brands, result.acq, result.website_id, result); self._renderHyperpayModal(result.checkoutId, result.domain, result.base_url, result.data_brands, result.acq, result.website_id);
} else { } else {
console.log("Error Occured"); console.log("Error Occured");
} }
}); });
}, },
_renderHyperpayModal: function (checkoutId, domain, base_url, data_brands, acq, website_id, result) { _renderHyperpayModal: function (checkoutId, domain, base_url, data_brands, acq, website_id) {
var self = this; var self = this;
try { try {
var $modal_html = $($(".payment_hyper_modal").get()[0]); var $modal_html = $($(".payment_hyper_modal").get()[0]);
$modal_html.appendTo($("body")).modal({ keyboard: false, backdrop: "static" }); $modal_html.appendTo($("body")).modal({ keyboard: false, backdrop: "static" });
var style_css = '<link rel="stylesheet" href="' + base_url + '/payment_hyperpay/static/src/css/hyperpay_style.css" />'; var style_css = '<link rel="stylesheet" href="' + base_url + '/payment_hyperpay/static/src/css/hyperpay_style.css" />';
var script = `<script async src="${domain}/v1/paymentWidgets.js?checkoutId=${checkoutId}" integrity="${result.integrity}" crossorigin="anonymous"></script>` var script = '<script async src="' + domain + "/v1/paymentWidgets.js?checkoutId=" + checkoutId + '"></script>';
var js_script = `<script src="/web/static/lib/jquery/jquery.js" nonce="${result.nonce}"></script>` var js_script = '<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>';
var shopperResultUrlTag = var shopperResultUrlTag =
'<form action="' + '<form action="' +
base_url + base_url +
@ -132,20 +131,10 @@ odoo.define("payment_hyperpay.payment_hyperpay", function (require) {
theIframe.style = "display:none"; theIframe.style = "display:none";
var html = script + shopperResultUrlTag; var html = script + shopperResultUrlTag;
let meta = `<meta http-equiv="Content-Security-Policy"
t-attf-content="
style-src 'self' https://*.oppwa.com 'unsafe-inline';
frame-src 'self' https://*.oppwa.com;
script-src 'self' https://*.oppwa.com https://src.mastercard.com https://p11.techlab-cdn.com 'nonce-${result.nonce}';
connect-src 'self' https://*.oppwa.com;
img-src 'self' https://*.oppwa.com;" />`
const url = getGeneratedPageURL({ const url = getGeneratedPageURL({
html: html, html: html,
css: style_css, css: style_css,
js: js_script, js: js_script,
meta: meta,
nonce: result.nonce
}); });
theIframe.src = url; theIframe.src = url;
$("#hyperpay-modal-body")[0].appendChild(theIframe); $("#hyperpay-modal-body")[0].appendChild(theIframe);