# Performing 3D Secure
This section describes how to perform 3D Secure if you are using the <intergiro-card-input>
tag. The tag does most of the heavy lifting of the 3D Secure process, but it does require some integration.
Any of the APIs that you might use to create an order will return a Verification required
error if the cardholder is required to perform SCA.
Example of Verification required
error:
{
"status": 400,
"type": "malformed content",
"error": "verification required",
"content": {
"property": "card",
"type": "Card.Creatable | Card.Token",
"description": "verification required",
"details": {
"visible": false,
"method": "POST",
"url": "https://acs.sandbox.3dsecure.io/3dsmethod",
"data": {
"type": "method",
"threeDSServerTransID": "d461f105-1792-407f-95ff-9a496fd918a9"
}
}
}
}
The received Verification required
error needs to be submitted together with the card token back to the <intergiro-card-input>
component which will initialize the 3D Secure cycle. This can result in rendering an invisible iframe for frictionless flow or a visible iframe that requires user interaction.
After the user interaction is completed, the <intergiro-card-input>
component will again produce a new card token which should be submitted to the same API again (e.g. create order API).
Note that it is possible for the Verification required
error to be received more then once, in which case the described cycle needs to be repeated until the API either returns a new created order or some other error.
# Snippet - 3D Secure when creating an order
<!DOCTYPE html>
<html>
<head>
<script type="module" src="https://merchant.intergiro.com/ui/"></script>
<link href="https://theme.intergiro.com/intergiro/variables.css" rel="stylesheet">
<script defer>
const order = {
number: "Card-Input-Example" + (Math.random() * 10000).toString(),
payment: { type: "card" },
items: 150,
currency: "EUR",
}
async function create(order, card, error) {
const element = document.querySelector("intergiro-card-input")
card = await element.submit(card, error)
let result
if (typeof card == "string") {
order.payment.card = card
order.id = error?.id // Add the id returned from the previous request.
const response = await fetch("https://merchant.intergiro.com/v1/order", {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
Authorization:
"Bearer <customer.api.key> | Bearer <private.api.key>",
},
method: "POST",
body: JSON.stringify(order),
})
result = response.headers.get("content-type").startsWith("application/json")
? await response.json()
: await response.text()
if (response.ok == true) {
alert(JSON.stringify(result));
} else {
result = create(order, card, result)
}
} else {
alert(JSON.stringify(card))
result = card
}
return result
}
</script>
</head>
<body style="width: 100%; max-width: 20em; margin-left: auto; margin-right: auto;">
<main>
<intergiro-card-input class="input"
api-key="<public.api.key>">
</intergiro-card-input>
<button type="submit" onclick="create(order)">Submit</button>
</main>
</body>
</html>
# Snippet - 3D Secure when creating a customer
<!DOCTYPE html>
<html>
<head>
<script type="module" src="https://merchant.intergiro.com/ui/"></script>
<link href="https://merchant.intergiro.com/theme/intergiro/index.css" rel="stylesheet">
<script defer>
async function create(customer, card, error) {
const element = document.querySelector("intergiro-card-input")
card = await element.submit(card, error)
let result
if (typeof card == "string") {
customer = customer ?? { method: [{ type: "token" }] }
customer.method[0].card = card
customer.id = error?.id // Add the id returned from the previous request.
const response = await fetch("https://merchant.intergiro.com/v1/customer", {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
Authorization:
"Bearer <private.api.key>",
},
method: "POST",
body: JSON.stringify(customer),
})
result = response.headers.get("content-type").startsWith("application/json")
? await response.json()
: await response.text()
if (response.ok == true) {
alert(Json.stringify(result))
} else {
result = create(customer, card, result)
}
} else {
alert(JSON.stringify(card))
result = card
}
return result
}
</script>
</head>
<body style="width: 100%; max-width: 20em; margin-left: auto; margin-right: auto;">
<main>
<intergiro-card-input class="input" api-key="<public.api.key>">
</intergiro-card-input>
<button type="submit" onclick="create()">Submit</button>
</main>
</body>
</html>
# Snippet - 3D Secure when creating an order with a saved card
To perform 3DS with a saved card, the <intergiro-payment-update>
element should be used. The customer that was created when the card was initially saved contains a method
property which is a list of saved cards, called payment methods. Select the payment method to be used when creating the order and assign it to the method
property of the element.
The submit function on the <intergiro-payment-update>
element has 2 optional input fields, payment
and error
.
Both input fields should be undefined in the first call. The function will return the card payment to be used in the /order
endpoint as indicated in the example below. If the order endpoint returnes a verification required
error, the submit function should be called again with the card payment returned from the previous call and the error.
If csc needs to be collected, set property
layout
to"csc"
. If no layout is specified or iflayout
is set to"none"
, the component will be invisible.
<!DOCTYPE html>
<html>
<head>
<script type="module" src="https://merchant.intergiro.com/ui/"></script>
<link href="https://theme.intergiro.com/intergiro/index.css" rel="stylesheet">
<script defer>
async function create(payment, error) {
let result
const element = document.querySelector("intergiro-payment-update")
payment = await element.submit(payment, error)
if (payment.card) {
const order = {
id: error?.id, // Add the id returned from the previous request.
items: 150,
currency: "EUR",
customer: "<customer-id>",
payment: payment,
}
const response = await fetch("https://merchant.intergiro.com/v1/order", {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
Authorization:
"Bearer <customer.api.key> | Bearer <private.api.key>",
},
method: "POST",
body: JSON.stringify(order),
})
result = await response.json()
if (response.ok == true) {
alert(JSON.stringify(result));
} else {
result = create(payment, result)
}
}
return result
}
</script>
</head>
<body>
<intergiro-payment-update
layout="csc"
method='{
"type": "card",
"created": "2020-03-13T13:37:13.123Z",
"token": "abc.def.ghi",
"scheme": "visa",
"iin": "411111",
"last4": "1111",
"expires": [ 2, 22 ],
}'
api-key="<public-api-key>">
</intergiro-payment-update>
<button type="submit" onclick="create()">Submit</button>
</body>
</html>