基于asp.net webform的网站集成支付网关。示例代码文档示例仅在php中。
我不确定如何继续前进,因为文档似乎没什么帮助
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>
赞赏任何帮助或指针
更新:
我正在尝试使用HTTPClient,但我不确定我是否正在使用它
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 }
我已更改return_auth
&amp; ivp_store
因为我无法分享它。任何指向正确的指针都会有很大的帮助。
我对文档感到困惑,所以要做正确的方法。他们似乎没有在他们的网站上有任何.net示例,而是他们有PHP插件,我不明白。
我在PHP中找到了wooCommerce插件的另一个例子
<?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><a href="https://www.telr.com/" target="_blank">Telr</a> <?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');
}
?>
答案 0 :(得分:2)
如果我使用邮递员并向https://secure.telr.com/gateway/order.json
发送以下请求,我会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
所以我猜您是以错误的方式构建了您的请求(尤其是Content-Type
,application/x-www-form-urlencoded
应该是application/json
,而不是ivp_store
。
我无法测试它,因为我没有{
"method": "create",
"trace": "4001/18544/587dfa99",
"error": {
"message": "E04:Invalid store ID"
}
}
参数,因此会出现以下回复:
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();
}
}
编辑:
以下是工作示例:
client.DefaultRequestHeaders.ExpectContinue = false;
请注意以下一行:
<!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
默认情况下, Expect: 100-continue
会发送@ResponseBody
@RequestMapping(value = "/view/{id}", method = RequestMethod.GET, produces = "application/pdf")
public ResponseEntity renderDocument(@AuthenticationPrincipal Principal principal, @PathVariable("id") Long id)
throws IOException {
Journal journal = journalRepository.findOne(id);
Category category = journal.getCategory();
CurrentUser activeUser = (CurrentUser) ((Authentication) principal).getPrincipal();
User user = userRepository.findOne(activeUser.getUser().getId());
List<Subscription> subscriptions = user.getSubscriptions();
Optional<Subscription> subscription = subscriptions.stream()
.filter(s -> s.getCategory().getId().equals(category.getId())).findFirst();
if (subscription.isPresent() || journal.getPublisher().getId().equals(user.getId())) {
File file = new File(PublisherController.getFileName(journal.getPublisher().getId(), journal.getUuid()));
InputStream in = new FileInputStream(file);
return ResponseEntity.ok(IOUtils.toByteArray(in));
} else {
return ResponseEntity.notFound().build();
}
}
@RequestMapping(method = RequestMethod.POST, value = "/publisher/publish")
@PreAuthorize("hasRole('PUBLISHER')")
public String handleFileUpload(@RequestParam("name") String name, @RequestParam("category")Long categoryId, @RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes, @AuthenticationPrincipal Principal principal) {
CurrentUser activeUser = (CurrentUser) ((Authentication) principal).getPrincipal();
Optional<Publisher> publisher = publisherRepository.findByUser(activeUser.getUser());
String uuid = UUID.randomUUID().toString();
File dir = new File(getDirectory(publisher.get().getId()));
createDirectoryIfNotExist(dir);
File f = new File(getFileName(publisher.get().getId(), uuid));
if (!file.isEmpty()) {
try {
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(f));
FileCopyUtils.copy(file.getInputStream(), stream);
stream.close();
Journal journal = new Journal();
journal.setUuid(uuid);
journal.setName(name);
journalService.publish(publisher.get(), journal, categoryId);
return "redirect:/publisher/browse";
} catch (Exception e) {
redirectAttributes.addFlashAttribute("message",
"You failed to publish " + name + " => " + e.getMessage());
}
} else {
redirectAttributes.addFlashAttribute("message",
"You failed to upload " + name + " because the file was empty");
}
return "redirect:/publisher/publish";
}
标题,这显然与您尝试连接的服务器混淆。