integration of 3D secure v2 for eboutic bank payment

This commit is contained in:
Thomas Girod
2022-11-28 17:03:46 +01:00
parent e43d53e564
commit fe9e5ce861
26 changed files with 1896 additions and 763 deletions

View File

@ -49,36 +49,27 @@ body {
font-family: sans-serif;
}
input[type=button], input[type=submit], input[type=reset],input[type=file] {
button, input[type=button], input[type=submit], input[type=reset],input[type=file] {
border: none;
text-decoration: none;
background-color: $background-button-color;
padding: 0.4em;
margin: 0.1em;
font-weight: bold;
font-size: 1.2em;
border-radius: 5px;
cursor: pointer;
box-shadow: $shadow-color 0px 0px 1px;
&:hover {
background: hsl(0, 0%, 83%);
}
}
&:hover {
background: hsl(0, 0%, 83%);
}
input[type=button], input[type=submit], input[type=reset],input[type=file] {
font-weight: bold;
}
button{
border: none;
text-decoration: none;
background-color: $background-button-color;
padding: 0.4em;
margin: 0.1em;
font-size: 1.18em;
border-radius: 5px;
box-shadow: $shadow-color 0px 0px 1px;
button:not(:disabled), input[type=button]:not(:disabled), input[type=submit]:not(:disabled), input[type=reset]:not(:disabled),input[type=file]:not(:disabled) {
cursor: pointer;
&:hover {
background: hsl(0, 0%, 83%);
}
}
input,textarea[type=text],[type=number]{
border: none;
text-decoration: none;
@ -123,6 +114,38 @@ a {
margin: 1px;
}
.collapse {
border-radius: 5px;
overflow: hidden;
.collapse-header {
color: white;
background-color: #354a5f;
padding: 5px 10px;
display: flex;
align-items: center;
gap: 10px;
.collapse-header-text {
flex: 2;
}
.collapse-header-icon {
transition: all ease-in-out 150ms;
&.reverse {
transform: rotate(180deg);
}
}
}
.collapse-body {
padding: 10px;
}
}
.shadow {
box-shadow: rgba(60, 64, 67, .3) 0 1px 3px 0, rgba(60, 64, 67, .15) 0 4px 8px 3px;
}
.w_big {
width: 75%;
}
@ -135,10 +158,12 @@ a {
width: 23%;
}
.clickable:hover {
.clickable:not(:disabled):hover {
cursor: pointer;
}
[x-cloak] { display: none !important; }
/*--------------------------------HEADER-------------------------------*/
#header_language_chooser {
@ -170,21 +195,11 @@ header {
background-color: $primary-neutral-dark-color;
border-radius: 0px 0px 10px 10px;
// PINKTOBER
// background-color: $pinktober;
// border-bottom: 5px solid $pinktober-secondary;
// margin-bottom: -5px;
// border-radius: 0 0 5px 7px;
#header_logo {
background-color: $white-color;
padding: 0.2em;
border-radius: 0px 0px 0px 9px;
//PINKTOBER
// border-bottom: 5px solid $shadow-color;
// border-radius: 0px 0px 0px 5px;
// margin-bottom: -5px;
border-radius: 0 0 0 9px;
a {
display: flex;
@ -211,14 +226,8 @@ header {
width: 100%;
label {
display: inline;
// PINKTOBER
// color: $pinktober-primary-text;
}
}
a {
display: button;
}
}
#header_bar {
@ -243,16 +252,6 @@ header {
flex: initial;
list-style-type: none;
margin: 0.2em 0.2em;
/*
PINKTOBER
& .fa.fa-times {
color: $pinktober-bar-closed !important;
}
& .fa.fa-check {
color: $pinktober-bar-opened !important;
}*/
}
#header_search {
@ -444,6 +443,36 @@ header {
}
}
.btn {
font-size: 15px;
font-weight: normal;
color: white;
min-width: 60px;
padding: 5px 10px;
border: none;
text-decoration: none;
&.btn-blue {
background-color: #354a5f;
}
&.btn-blue:disabled {
background-color: rgba(70, 90, 126, 0.4);
}
&.btn-blue.clickable:not(:disabled):hover {
background-color: #2c3646;
}
&.btn-grey {
background-color: grey;
}
&.btn-grey.clickable:not(:disabled):hover {
background-color:hsl(210,5%,30%);
}
}
/*--------------------------------CONTENT------------------------------*/
#quick_notif {
width: 100%;
@ -465,10 +494,7 @@ header {
.alert {
margin: 10px;
border: #fc8181 1px solid;
background-color: rgb(255,245,245);
border-radius: 4px;
color: #c53030;
padding: 12px 16px;
display: flex;
gap: 16px;
@ -476,6 +502,18 @@ header {
align-items: center;
text-align: justify;
&.alert-green {
background-color: rgb(245, 255, 245);
color: rgb(3, 84, 63);
border: rgb(14, 159, 110) 1px solid;
}
&.alert-red {
background-color: rgb(255,245,245);
color: #c53030;
border: #fc8181 1px solid;
}
.alert-main {
flex: 2;
}
@ -1496,7 +1534,7 @@ textarea {
margin: 10px 0;
display: flex;
flex-wrap: wrap;
height: 20p;
height: 20px;
align-items: center;
}
.search_check {

View File

@ -1,191 +0,0 @@
#eboutic {
display: flex;
flex-direction: row-reverse;
align-items: flex-start;
column-gap: 20px;
margin: 0 20px 20px;
}
#eboutic-title {
margin-left: 20px;
}
#eboutic h3 {
margin-left: 0;
margin-right: 0;
}
#basket {
min-width: 300px;
border-radius: 8px;
box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 4px 8px 3px;
padding: 10px;
}
#basket h3 {
margin-top: 0;
}
@media screen and (max-width: 765px) {
#eboutic {
flex-direction: column;
align-items: center;
margin: 10px;
row-gap: 20px;
}
#eboutic-title {
margin-bottom: 20px;
margin-top: 4px;
}
#basket {
}
}
#eboutic #basket .error-message {
margin-top: 5px;
background-color: #f8d7da;
border: #f5c6cb 1px solid;
border-radius: 4px;
padding: 10px;
display: flex;
flex-direction: column;
row-gap: 7px;
}
#eboutic #basket .error-message p {
margin: 0;
}
#eboutic .item-list {
margin-left: 0;
list-style: none;
}
#eboutic .item-list li {
display: flex;
align-items: center;
margin-bottom: 10px
}
#eboutic .item-name {
flex: 1;
}
#eboutic .item-price, #eboutic .item-quantity {
width: 65px;
}
#eboutic .item-quantity {
text-align: center;
}
#eboutic .fa-plus, #eboutic .fa-minus {
cursor: pointer;
}
#eboutic .item-price {
text-align: right;
}
/* CSS du catalogue */
#eboutic #catalog {
display: flex;
flex-grow: 1;
flex-direction: column;
row-gap: 30px;
}
#eboutic .category-header {
margin-bottom: 15px;
}
#eboutic .product-group {
display: flex;
flex-wrap: wrap;
column-gap: 15px;
row-gap: 15px;
}
@media screen and (max-width: 765px) {
#eboutic #catalog {
row-gap: 15px;
}
#eboutic section {
text-align: center;
}
#eboutic .product-group {
justify-content: space-around;
}
}
#eboutic .product-button {
position: relative;
box-sizing: border-box;
min-width: 120px;
max-width: 150px;
padding: 10px;
overflow: hidden;
box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 4px 8px 3px;
display: flex;
flex-direction: column;
align-items: center;
row-gap: 5px;
}
#eboutic .product-button:active {
box-shadow: none;
}
#eboutic .product-button img, #eboutic .product-button .fa {
margin: 0;
border-radius: 4px;
height: 40px;
line-height: 40px;
}
#eboutic .product-button p {
font-size: 13px;
margin: 0;
}
#eboutic .catalog-buttons {
display: flex;
justify-content: center;
column-gap: 30px;
margin: 30px 0 0;
}
#eboutic input {
all: unset;
}
#eboutic .catalog-buttons button {
font-size: 15px;
font-weight: normal;
color: white;
min-width: 60px;
padding: 5px 10px;
}
#eboutic .catalog-buttons .validate {
background-color: #354a5f;
}
#eboutic .catalog-buttons .clear {
background-color: gray;
}
#eboutic .catalog-buttons button i {
margin-right: 4px;
}
#eboutic .catalog-buttons button.validate:hover {
background-color: #2c3646;
}
#eboutic .catalog-buttons button.clear:hover {
background-color:hsl(210,5%,30%);
}
#eboutic .catalog-buttons form {
margin: 0;
}

View File

@ -1,104 +0,0 @@
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function get_starting_items() {
const cookie = getCookie("basket_items")
try {
// django cookie backend does an utter mess on non-trivial data types
// so we must perform a conversion of our own
const biscuit = JSON.parse(JSON.parse(cookie.replace(/\\054/g, ',')));
if (Array.isArray(biscuit)) {
return biscuit;
}
return [];
} catch (e) {
return [];
}
}
document.addEventListener('alpine:init', () => {
Alpine.data('basket', () => ({
items: get_starting_items(),
get_total() {
let total = 0;
for (const item of this.items) {
total += item["quantity"] * item["unit_price"];
}
return total;
},
add(item) {
item.quantity++;
this.edit_cookies()
},
remove(item_id) {
const index = this.items.findIndex(e => e.id === item_id);
if (index < 0) return;
this.items[index].quantity -= 1;
if (this.items[index].quantity === 0) {
this.items = this.items.filter((e) => e.id !== this.items[index].id);
}
this.edit_cookies();
},
clear_basket() {
this.items = []
this.edit_cookies();
},
edit_cookies() {
// a cookie survives an hour
document.cookie = "basket_items=" + JSON.stringify(this.items) + ";Max-Age=3600";
},
/**
* Create an item in the basket if it was not already in
* @param id : int the id of the product to add
* @param name : String the name of the product
* @param price : number the unit price of the product
*/
create_item(id, name, price) {
let new_item = {
id: id,
name: name,
quantity: 0,
unit_price: price
};
this.items.push(new_item);
this.add(new_item);
},
/**
* add an item to the basket.
* This is called when the user click
* on a button in the catalog (left side of the page)
* @param id : int the id of the product to add
* @param name : String the name of the product
* @param price : number the unit price of the product
*/
add_from_catalog(id, name, price) {
const item = this.items.find(e => e.id === id)
if (item === undefined) {
this.create_item(id, name, price);
} else {
// the user clicked on an item which is already in the basket
this.add(item);
}
},
}))
})