Stripe Error 400 - Cannot use stripe token more than once - javascript

I keep receiving error code 400 on my stripe dashboard. It seems like im using the same stripe token more than once and this produces an error. Below is my code.
Js:
<script src="https://checkout.stripe.com/checkout.js"></script>
<script>
var handler = StripeCheckout.configure({
key: 'pk_test_******************',
image: '/img/documentation/checkout/marketplace.png',
token: function(token) {
/*$.post("php/charge.php",{stripeToken:token.id},function(data,status){
console.log("Data: "+ data+"\nStatus: "+status);
});*/
alert(token.used);//alerts false
$.post("php/charge.php",{stripeToken:token.id});
alert(token.used);// still alerts false
}
});
$('#myButton').on('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'Demo Site',
description: '2 widgets',
currency: "cad",
amount: 2000
});
e.preventDefault();
});
// Close Checkout on page navigation
$(window).on('popstate', function() {
handler.close();
});
</script>
Php:
<?php
require_once('config.php');
$token = $_POST['stripeToken'];
$customer = \Stripe\Customer::create(array(
'email' => 'test#test.com',
'card' => $token
));
//try {
$charge = \Stripe\Charge::create(array(
"amount" => 1000, // amount in cents, again
"currency" => "cad",
"source" => $token,
"description" => "Example charge")
);
//}catch(\Stripe\Error\Card $e) {
// The card has been declined
//}
?>
Can anyone tell my why I cant charge a customer? How am I using a key multiple times?

You do use the token twice.
First, when creating the customer.
Second, when trying to charge the card.
Instead, you can create a customer and and then pass $customer->id to Stripe when you create the charge:
$charge = \Stripe\Charge::create(array(
"amount" => 1000, // amount in cents, again
"currency" => "cad",
"customer" => $customer->id,
"description" => "Example charge")
);

You have to create the customer to charge him multiple times.
1) Add the Credit card token to customer and create customer
2) Use the customer Id to charge users
if (isset($_POST['stripeToken'])){
$token = $_POST['stripeToken'];
// Create a Customer
$customer = \Stripe\Customer::create(array(
"source" => $token,
"description" => "Example customer")
);
// Charge the Customer instead of the card
\Stripe\Charge::create(array(
"amount" => 1000, # amount in cents, again
"currency" => "usd",
"customer" => $customer->id)
);
}
for more help visit: https://stripe.com/docs/tutorials/charges

Related

how do we retrive checkout session in stripe success page

This is my server side code
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
use Slim\Http\Request;
use Slim\Http\Response;
use Stripe\Stripe;
require 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->load();
require './config.php';
$app = new \Slim\App;
$app->add(function ($request, $response, $next) {
Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));
return $next($request, $response);
});
$app->get('/', function (Request $request, Response $response, array $args) {
return $response->write(file_get_contents(getenv('STATIC_DIR') . '/index.html'));
});
$app->post('/checkout_sessions', function(Request $request, Response $response) use ($app) {
$params = json_decode($request->getBody());
$payment_method_types = [
'usd' => ['card'],
'eur' => ['card'],
'cad' => ['card']
];
$products = [
'cause-a' => 'prod_KP3YP2a3IGYqsb',
'cause-b' => 'prod_KP3iZRGcEjn5W8',
];
$session = \Stripe\Checkout\Session::create([
'success_url' => 'http://localhost:4242/success.html?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => 'http://localhost:4242/?cancel=true',
'mode' => 'payment',
'payment_method_types' => $payment_method_types[$params->currency],
'metadata' => [
'cause' => $params->cause,
'currency' => $params->currency,
],
'submit_type' => 'donate',
'line_items' => [[
'price_data' => [
'currency' => $params->currency,
'product' => $products[$params->cause],
'unit_amount' => $params->amount,
],
'quantity' => 1,
]]
]);
return $response->withJson([
'id' => $session->id
]);
});
$app->get('/order', function (Request $request, Response $response) {
$id = $_GET['sessionId'];
$checkout_session = \Stripe\Checkout\Session::retrieve($id);
echo json_encode($checkout_session);
});
$app->run();
this is the success page with javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Order Confirm</title>
</head>
<body>
<div id="main">
<div id="checkout">
<div id="payment-forum">
<h1>Success</h1>
payment status: <span id="payment-status"></span>
<pre>
</pre>
</div>
</div>
</div>
</body>
<script>
var paymentStatus = document.getElementById('payment-status');
var urlParams = new URLSearchParams(window.location.search);
var sessionId = urlParams.get("session_id")
if (sessionId) {
fetch("/order?sessionId=" + sessionId).then(function(result){
return result.json()
}).then(function(session){
var sessionJSON = JSON.stringify(session, null, 2);
document.querySelector("pre").textContent = sessionJSON;
}).catch(function(err){
console.log('Error when fetching Checkout session', err);
});
}
</script>
</html>
i need help with product detail , customer name , amount on success page and if possible payment paid or not paid status on it.... cant find any tutorial on it or any detail step by step guide on it
i am close but cant get it to bullseyes please help me with it
yeah on success page all i get is payment status and blank
Looks like here is what happened:
Your Checkout Session defined success_url to success.html
Your success.html fired another request to "/success?session_id=xxx"
Your backend handled this with $app->get('/success', function...
It could be confusing to name both HTML in step 2 and the handling URL in step 3 as "success". You may want to use a different name such as "success" and "get-checkout-session" like Stripe example on Github. After that, debug your server log on step 3 to see whether you got the session id correctly and have retrieved the Customer Id.
There is more information to extract from a CheckoutSession. See Stripe's API Reference on available properties. You probably want to expand its payment_intent to see the amount and payment status.

static amount not variable

how can i send variable amount on my line item as it only accept integers please rest everything works but this varible amount is not working tried $params->amount not working
<?php
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey('sk_test_key');
$session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [[
'price_data' => [
'currency' => 'usd',
'product_data' => [
'name' => 'T-shirt',
],
'unit_amount' => 2000,
],
'quantity' => 1,
]],
'mode' => 'payment',
'success_url' => 'https://example.com/success',
'cancel_url' => 'https://example.com/cancel',
]);
?>
<html>
<head>
<title>Buy cool new product</title>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<div class="field">
<label for="amount">Amount to pay</label>
<input type="number" id="amount" step="0.01" value="5.00">
</div>
<button id="checkout-button">Checkout</button>
<script>
var stripe = Stripe('pk_test_51JWkHLK7X12cK8Ptf5y5DQn6Ugf6miu3AqSuhH9wdLsyTB9ouf0TY31vDQxq19xIt6YH76uMTEX1kU9HMyrcEb6w00MTxHnGxc');
var amount = document.getElementById('amount');
const btn = document.getElementById("checkout-button")
btn.addEventListener('click', function(e) {
e.preventDefault();
stripe.redirectToCheckout({
sessionId: "<?php echo $session->id; ?>"
});
})
</script>
</body>
</html>
how can i send variable amount on my line item as it only accept integers please rest everything works but this varible amount is not working tried $params->amount not working
The code to create the payment intent with your secret key needs to be run server-side - you must not use your secret key in client-side code.
You should follow the guide here to see how you can generate a payment intent and provide the secret key in a server rendered template, or you can make an async request to your server from an SPA to get a payment intent client secret. The guide goes through both options.

Stripe redirectToCheckout with Laravel 6/JavaScript

I'm trying stripe.redirectToCheckout in Laravel 6. And it's been days now, I can't find anything helpful on internet. I used strip documentation for creating a user session and redirectToCheckout and implemented stripe session in web/routes and redirectToCheckout in JavaScript.
The following is the button for pay with stripe
<button id="checkout-button"
data="{{$id}}" href="https://checkout.stripe.com/checkout.js"
role="link" style="width: 100%"
class="btn btn-dark">Pay with stripe
</button>
The following is the JavaScript function for redirectToCheckout
<script>
(function () {
var stripe = window.Stripe('pk_test_ZuGUA3XxCsWvZVbqnOkFMQnM00PV2c0Acm');
var checkoutButton = document.getElementById('checkout-button');
checkoutButton.addEventListener('click', function () {
// When the customer clicks on the button, redirect
// them to Checkout.
console.log('button clicked');
var product_name = document.getElementById('#p_name');
var product_price = document.getElementById('#p_price');
var name, price;
// var checkout_btn = document.getElementById('#checkout-button-plan_GI1dhi4ljEzk0R');
btn = $(this).attr('data');
console.log(btn);
stripe.redirectToCheckout({
items: [
// Replace with the ID of your SKU
{sku: 'sku****', quantity: 1}
],
successUrl: 'http://4c655de9.ngrok.io/success',
cancelUrl: 'http://4c655de9.ngrok.io/canceled',
clientReferenceId: btn
}).then(function (result) {
console.log('result');
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
console.log(result.error.message);
});
});
})();
</script>
The following is the web/route.php function for \Stripe\Checkout\Session
Route::get('/', function () {
\Stripe\Stripe::setApiKey('sk****');
$session = \Stripe\Checkout\Session::create([
'success_url' => 'http://4c655de9.ngrok.io/success',
'cancel_url' => 'http://4c655de9.ngrok.io/canceled',
'payment_method_types' => ['card'],
'line_items' => [
[
'name' => 'T-shirt',
'description' => 'Comfortable cotton t-shirt',
'amount' => 1500,
'currency' => 'usd',
'quantity' => 2,
],
],
]);
$id = $session->id;
return view('home')->with('id', $id);

Integrating stripe payments (JS and PHP) with a custom amount (JS variable)

I've been trying to figure this out for days with no luck.
I'm trying to implement Stripe Payments Checkout into my website. The payment amount is on the payments page as a JS variable. I was able to get Basic Checkout working, but apparently that can't use a custom amount, or send any data to the PHP processing page (email, and some order attributes). I've been trying to use the Custom Checkout but I can't figure it out. Any help?
So far I have this in config.php:
<?php
require_once('vendor/autoload.php');
$stripe = array(
"secret_key" => "MY SECRET KEY IS HERE",
"publishable_key" => "MY PUBLISHED KEY IS HERE"
);
\Stripe\Stripe::setApiKey($stripe['secret_key']);
?>
and this is in a file called process.php:
<?php
require_once('./config.php');
$token = $_POST['stripeToken'];
$input = $_POST["totalprice"];
$customer = \Stripe\Customer::create(array(
'email' => 'customer#example.com',
'source' => $token
));
$charge = \Stripe\Charge::create(array(
'customer' => $customer->id,
'amount' => $input,
'currency' => 'usd'
));
echo $input;
?>
And in the initial PHP file I have:
<?php require_once('./config.php'); ?>
<form action="process.php" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="MY PUBLIC TEST KEY IS HERE"
data-amount= amt * 100
data-name="Test Name"
data-description="Widget"
data-image="/img/logo.jpg"
data-locale="auto"
>
<form type=hidden name="totalprice" value=amt*100 action="process.php" method="POST">
</script>
</form>
With that said though, I've had a bunch of other code I've tried before that hasn't worked, so this current code probably should be scrapped. I'd really appreciate any help I can get!
Well, following is the sample code of Custom Integration.
<script src="https://checkout.stripe.com/checkout.js"></script>
<button id="customButton">Purchase</button>
<script>
var handler = StripeCheckout.configure({
key: 'pk_test_6pRNASCoBOKtIshFeQd4XMUh',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function(token) {
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
}
});
document.getElementById('customButton').addEventListener('click', function(e) {
// Open Checkout with further options:
handler.open({
name: 'Stripe.com',
description: '2 widgets',
zipCode: true,
amount: 2000
});
e.preventDefault();
});
// Close Checkout on page navigation:
window.addEventListener('popstate', function() {
handler.close();
});
</script>
The source code is given on this page
So is that what you are looking for?

Integrating Payment Gateway in ASP.NET

integration payment gateway in asp.net webform based website. sample code documentation examples are in php only.
I am not sure how to go forward as documentation doesnt seem to be of much help
https://telr.com/support/knowledge-base/hosted-payment-page-integration-guide/
<%# Page Language="C#" AutoEventWireup="true" CodeFile="PaymentProcess.aspx.cs" Inherits="PaymentProcess" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<style>
#telr {
width: 100%;
min-width: 600px;
height: 600px;
frameborder: 0;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<p> Enter You Credit Card Details Here</p>
<p><iframe id= " telr " src= " [url obtained from create order] " ></iframe></p>
<div>
</div>
</form>
<script type="text/javascript">
</script>
</body>
</html>
Any help or pointer is appreciated
UPDATE:
I am trying to using HTTPClient for same but i am not sure if i am doing it wring
protected void btn_Click(object sender, EventArgs e)
{
using (var client = new HttpClient())
{
TelrObj obj = new TelrObj();
obj.ivp_method = "create";
obj.ivp_store = 12345;
obj.ivp_cart = "cardid1234";
obj.ivp_test = 1;
obj.return_auth = "xxxx-xxxx-xxx";
obj.return_can = "";
obj.return_decl = "";
obj.ivp_amount = 10;
obj.bill_fname = "David";
obj.ivp_currency = "USD";
var str = "{ 'method':'create', 'order':{ 'ref':'OrderRef', 'cartid':'cardid1234', 'test':1,'amount':10,'currency':'USD', 'url':'https://secure.telr.com/gateway/process.html?o=OrderRef' }";
var response = client.PostAsync("https://secure.telr.com/gateway/order.json",
new StringContent(JsonConvert.SerializeObject(str).ToString(),
Encoding.UTF8, "application/json"))
.Result;
Response.Write(response);
if (response.IsSuccessStatusCode)
{
dynamic content = JsonConvert.DeserializeObject(
response.Content.ReadAsStringAsync()
.Result);
// Access variables from the returned JSON object
var appHref = content.links.applications.href;
}
}
}
RESPONSE
StatusCode: 417, ReasonPhrase: 'Expectation Failed', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Connection: close Date: Tue, 17 Jan 2017 10:52:30 GMT Server: Apache Content-Length: 364 Content-Type: text/html; charset=iso-8859-1 }
I have changed return_auth & ivp_store as i cant share it. Any pointer to do it right would be of great help.
I am confused with there documentation so to do it right way. They dont seem to have any .net example on their website rather they have PHP Plugins which i don't understand.
I found another example for wooCommerce plugin which is in PHP
<?php
if (!defined('ABSPATH')) { exit; } // Exit if accessed directly
if (!defined('WP_CONTENT_URL')) { define('WP_CONTENT_URL', get_option('siteurl').'/wp-content'); }
if (!defined('WP_PLUGIN_URL')) { define('WP_PLUGIN_URL', WP_CONTENT_URL.'/plugins'); }
if (!defined('WP_CONTENT_DIR')) { define('WP_CONTENT_DIR', ABSPATH.'wp-content'); }
if (!defined('WP_PLUGIN_DIR')) { define('WP_PLUGIN_DIR', WP_CONTENT_DIR.'/plugins'); }
function telr_init() {
/**
* __construct function.
*
* #access public
* #return void
*/
class WC_Gateway_Telr extends WC_Payment_Gateway {
public function __construct() {
global $woocommerce;
$this->min_wc_ver="2.3.8";
$this->id = 'telr';
$this->has_fields = false; // No additional fields in checkout page
$this->method_title = __('Telr', 'woocommerce');
$this->method_description = __('Telr Checkout', 'telr-for-woocommerce');
$this->order_button_text = __( 'Proceed to Telr', 'telr-for-woocommerce' );
$this->woocom_ver = $woocommerce->version;
// Load the settings.
$this->init_form_fields(); // Config page fields
$this->init_settings();
if ($this->can_init()) {
$preload='<iframe style="width:1px;height:1px;visibility:hidden;display:none;" src="https://secure.telrcdn.com/preload.html"></iframe>';
$this->enabled = $this->get_config_option('enabled');
$this->title = $this->get_config_option('title');
$this->description = $this->get_config_option('description').$preload;
$this->store_id = $this->get_config_option('store_id');
$this->store_secret = $this->get_config_option('store_secret');
$this->testmode = $this->get_config_option('testmode');
$this->debug = $this->get_config_option('debug');
$this->order_status = $this->get_config_option('order_status');
$this->cart_desc = $this->get_config_option('cart_desc');
$this->form_submission_method = true;
$this->api_endpoint = 'https://secure.telr.com/gateway/order.json';
// Actions
add_action('woocommerce_update_options_payment_gateways_'.$this->id, array($this, 'process_admin_options'));
add_action( 'woocommerce_thankyou', array($this, 'update_order_status'));
} else {
$this->enabled = false;
}
}
private function can_init() {
if (version_compare(PHP_VERSION, '5.5.0') < 0) {
return false;
}
if (!function_exists('curl_version')) { return false; }
if (!function_exists('curl_init')) { return false; }
if (version_compare($this->woocom_ver,$this->min_wc_ver) < 0) {
return false;
}
return true;
}
public function update_order_status($order_id) {
global $woocommerce;
$order = new WC_Order( $order_id );
$order_check = $this->check_order($order_id);
if($order_check) {
$new_status = $this->sorder_status;
if (empty($new_status)) { $new_status="completed"; }
$order->update_status($new_status);
}
}
/**
* Process the payment and return the result.
*
* #access public
* #return array
*/
function process_payment($order_id) {
$order = new WC_Order($order_id);
$result = $this->generate_request($order);
$telr_ref = trim($result['order']['ref']);
$telr_url= trim($result['order']['url']);
if (empty($telr_ref) || empty($telr_url)) {
wc_add_notice('Payment API Failure, Please try again.', 'error');
} else {
update_post_meta( $order_id, '_telr_ref', $telr_ref);
}
return array(
'result' => 'success',
'redirect' => $telr_url,
);
}
public function generate_request($order) {
global $woocommerce;
$order_id = $order->id;
$cart_id = $order_id."_".uniqid();
$cart_desc=trim($this->cart_desc);
if (empty($cart_desc)) { $cart_desc='Order {order_id}'; }
$cart_desc = preg_replace('/{order_id}/i',$order_id,$cart_desc);
$test_mode = ($this->testmode == 'yes') ? 1 : 0;
$return_url = 'auto:'.add_query_arg('utm_nooverride','1',$this->get_return_url($order));
$cancel_url = 'auto:'.$order->get_cancel_order_url();
$data = array(
'ivp_method' => "create",
'ivp_source' => 'WooCommerce '.$woocommerce->version,
'ivp_store' => $this->store_id ,
'ivp_authkey' => $this->store_secret,
'ivp_cart' => $cart_id,
'ivp_test' => $test_mode,
'ivp_amount' => $order->order_total,
'ivp_currency' => get_woocommerce_currency(),
'ivp_desc' => $cart_desc,
'return_auth' => $return_url,
'return_can' => $cancel_url,
'return_decl' => $cancel_url,
'bill_fname' => $order->billing_first_name,
'bill_sname' => $order->billing_last_name,
'bill_addr1' => $order->billing_address_1,
'bill_addr2' => $order->billing_address_2,
'bill_city' => $order->billing_city,
'bill_region' => $order->billing_state,
'bill_zip' => $order->billing_postcode,
'bill_country' => $order->billing_country,
'bill_email' => $order->billing_email,
);
if (is_ssl() && is_user_logged_in()) {
$data['bill_custref'] = get_current_user_id();
}
$response = $this->api_request($data);
return $response;
}
public function check_order($order_id) {
global $woocommerce;
$order_ref = get_post_meta($order_id, '_telr_ref', true);
$data = array(
'ivp_method' => "check",
'ivp_store' => $this->store_id ,
'order_ref' => $order_ref,
'ivp_authkey' => $this->store_secret,
);
$response = $this->api_request($data);
$order_status_arr = array(2,3);
$transaction_status_arr = array('A', 'H');
if (array_key_exists("order", $response)) {
$order_status = $response['order']['status']['code'];
$transaction_status = $response['order']['transaction']['status'];
if ( in_array($order_status, $order_status_arr) && in_array($transaction_status, $transaction_status_arr)) {
return true;
}
}
return false;
}
public function api_request($data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->api_endpoint);
curl_setopt($ch, CURLOPT_POST, count($data));
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
$results = curl_exec($ch);
curl_close($ch);
$results = json_decode($results,true);
return $results;
}
/* ------------------------------ Admin setting page ------------------------------------------------ */
public function get_config_option($key) {
return $this->get_option($key);
}
public function admin_options() {
if ($this->can_init()) {
$this->show_admin_options();
} else {
$this->not_available();
}
}
public function not_available() {
?>
<div class="inline error"><p><strong><?php _e( 'Gateway Disabled', 'woocommerce' ); ?></strong>: <?php _e( sprintf('Requires WooCommerce %s or later, PHP 5.5 or later, and PHP cURL',$this->min_wc_ver), 'woocommerce' ); ?></p></div>
<?php
}
public function show_admin_options() {
// Admin Panel Options
$configured = true;
if ((empty($this->store_id)) || (empty($this->store_secret))) { $configured=false; }
?>
<h3><?php _e('Telr', 'woocommerce'); ?></h3>
<?php if (!$configured) : ?>
<div id="wc_get_started">
<span class="main"><?php _e('Telr Hosted Payment Page', 'woocommerce'); ?></span>
<span>Telr <?php _e('are a PCI DSS Level 1 certified payment gateway. We guarantee that we will handle the storage, processing and transmission of your customer\'s cardholder data in a manner which meets or exceeds the highest standards in the industry.', 'woocommerce'); ?></span>
<span><br><b>NOTE: </b> You must enter your store ID and authentication key</span>
</div>
<?php else : ?>
<p><?php _e('Telr Hosted Payment Page', 'woocommerce'); ?></p>
<?php endif; ?>
<table class="form-table">
<?php $this->generate_settings_html(); ?>
</table><!--/.form-table-->
<?php
}
// Admin settings fields
function init_form_fields() {
// Initialise Gateway Settings Form Fields
$this->form_fields = array(
'enabled' => array(
'title' => __('Enable/Disable', 'woocommerce'),
'type' => 'checkbox',
'label' => __('Enable Telr', 'woocommerce'),
'default' => 'yes'
),
'title' => array(
'title' => __('Title', 'woocommerce'),
'type' => 'text',
'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),
'default' => __('Credit/Debit card', 'woocommerce'),
'desc_tip' => true,
),
'description' => array(
'title' => __('Description', 'woocommerce'),
'type' => 'textarea',
'description' => __('This controls the description which the user sees during checkout.', 'woocommerce'),
'default' => __('Pay using a credit or debit card via Telr Secure Payments', 'woocommerce'),
'desc_tip' => true,
),
'cart_desc' => array(
'title' => __('Transaction description', 'woocommerce'),
'type' => 'text',
'description' => __('This controls the transaction description shown within the hosted payment page.', 'woocommerce'),
'default' => __('Your order from StoreName', 'woocommerce'),
'desc_tip' => true,
),
'store_id' => array(
'title' => __('Store ID', 'woocommerce'),
'type' => 'text',
'description' => __('Enter your Telr Store ID.', 'woocommerce'),
'default' => '',
'desc_tip' => true,
'placeholder' => '[StoreID]'
),
'store_secret' => array(
'title' => __('Authentication Key', 'woocommerce'),
'type' => 'text',
'description' => __('This value must match the value configured in the hosted payment page V2 settings', 'woocommerce'),
'default' => '',
'desc_tip' => true,
'placeholder' => '[Authentication Key]'
),
'testmode' => array(
'title' => __('Test Mode', 'woocommerce'),
'type' => 'checkbox',
'label' => __('Generate transactions in test mode', 'woocommerce'),
'default' => 'yes',
'description' => __('Use this whilst testing your integration. You must disable test mode when you are ready to take live transactions')
),
'order_status' => array(
'title' => __('Order Status', 'woocommerce'),
'type' => 'select',
'label' => __('Order status for authorised payments', 'woocommerce'),
'default' => 'processing',
'description' => __('Set the WooCommerce order status that will be used for authorised transations', 'woocommerce'),
'options' => array(
'processing' => __( 'Processing', 'woocommerce' ),
'completed' => __( 'Completed', 'woocommerce' )
)
)
);
}
}
}
if(!function_exists('telr_list_network_plugins')) {
function telr_list_network_plugins() {
if (!is_multisite()) {
return false;
$sitewide_plugins = array_keys((array) get_site_option('active_sitewide_plugins'));
}
if (!is_array($sitewide_plugins)) {
return false;
}
return $sitewide_plugins;
}
}
function add_telr_gateway($methods) {
$methods[] = 'WC_Gateway_Telr';
return $methods;
}
// Add plugin to wordpress/woocommerce
if ((in_array('woocommerce/woocommerce.php', (array)get_option('active_plugins'))) || (in_array('woocommerce/woocommerce.php', (array)telr_list_network_plugins()))) {
add_action('plugins_loaded', 'telr_init', 0);
add_filter('woocommerce_payment_gateways', 'add_telr_gateway');
}
?>
If I use Postman and send a following request to the https://secure.telr.com/gateway/order.json I'm getting HTTP 200:
POST /gateway/order.json HTTP/1.1
Host: secure.telr.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 570a44c1-9c4e-58b2-5d4d-fdd352272235
ivp_method=create&ivp_store=12345&ivp_authkey=12345&ivp_cart=12345&ivp_test=1&ivp_amount=100.00&ivp_currency=AED&ivp_desc=Description&return_auth=https%3A%2F%2Fdomain.com%2Freturn.html&return_can=https%3A%2F%2Fdomain.com%2Freturn.html&return_decl=https%3A%2F%2Fdomain.com%2Freturn.html
So I guess you're building your request in a wrong way(especially Content-Type which should be application/x-www-form-urlencoded, not application/json).
I cannot test it more since I don't ivp_store parameter, thus following response appears:
{
"method": "create",
"trace": "4001/18544/587dfa99",
"error": {
"message": "E04:Invalid store ID"
}
}
EDIT:
Here's working example:
static void Main(string[] args)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://secure.telr.com/");
client.DefaultRequestHeaders.ExpectContinue = false;
var result = client.PostAsync("gateway/order.json",
new FormUrlEncodedContent(new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("ivp_method", "create"),
new KeyValuePair<string, string>("ivp_store", "12345"),
new KeyValuePair<string, string>("ivp_authkey", "12345"),
new KeyValuePair<string, string>("ivp_cart", "12345"),
new KeyValuePair<string, string>("ivp_desc", "Desc"),
new KeyValuePair<string, string>("ivp_test", "1"),
new KeyValuePair<string, string>("ivp_amount", "100.00"),
new KeyValuePair<string, string>("ivp_currency", "AED"),
new KeyValuePair<string, string>("return_auth", "https://wwww.google.pl"),
new KeyValuePair<string, string>("return_can", "https://wwww.google.pl"),
new KeyValuePair<string, string>("return_decl", "https://wwww.google.pl"),
})).Result;
Console.WriteLine(result.Content.ReadAsStringAsync().Result);
Console.ReadLine();
}
}
Note following line:
client.DefaultRequestHeaders.ExpectContinue = false;
which is required for this server. If you do not include this line and run my code, you will get following response:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>417 Expectation Failed</title>
</head><body>
<h1>Expectation Failed</h1>
<p>The expectation given in the Expect request-header
field could not be met by this server.
The client sent<pre>
Expect: 100-continue
</pre>
</p><p>Only the 100-continue expectation is supported.</p>
</body></html>
HttpClient by default sends a Expect: 100-continue header, which clearly messes with a server you're trying to connect.

Categories