i am using the authorize.net as my payment gateway which accept payment from credit card
the code is as follows
$ex=JRequest::getVar('exp2','');
$amount1=JRequest::getVar('amounttrue','');
if($amount1!="")
{
//echo"dsfgdsf";
$amount=$amount1;
//echo $amount;die;
}//echo $amount;die;
$post_url = "https://test.authorize.net/gateway/transact.dll";
$amount =$_POST['amount'];
$amount =$_POST['amounttrue'];
$card_num=$_POST['ccn'];
$first_name=$_POST['firstname'];
$last_name=$_POST['lastname'];
$address1=$_POST['address1'];
$state=$_POST['state'];
$zipcode=$_POST['zipcode'];
$ccname=$_POST['ccname'];
$db=&JFactory::getDBO();
$query="select * from #__book_gateway where id=1";
$db->setQuery($query);
$result=$db->loadObjectlist();
//print_r($result);die;
foreach($result as $info)
{ $login=$info->api_user_name;
$pass=$info->api_password;//die;
}//print_r($login);die;
$post_values = array(
// the API Login ID and Transaction Key must be replaced with valid values
"x_login" => "$login",
"x_tran_key" => "$pass",
//"x_login" => "52y88ZGH9f9",
//"x_tran_key" => "5rG9j97Ce46xAZzY",
/*"x_login" => "52y88ZGH9f1",
"x_tran_key" => "5rG9j97Ce46xAZzY",*/
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
"x_type" => "AUTH_CAPTURE",
"x_method" => "CC",
//"x_card_num" => "4111111111111111",
"x_card_num" => "$card_num",
//"x_exp_date" => "0115",
"x_exp_date" => "$ex",
"x_amount" =>" $amount",
//"x_amount" => "19.99",
//"x_description" => "Sample Transaction",
"x_description" =>"$ccname",
//"x_first_name" => "John",
"x_first_name" =>"$first_name",
//"x_last_name" => "Doe",
"x_last_name" => "$last_name",
//"x_address" => "1234 Street",
"x_address" => "$address1",
//"x_state" => "WA",
"x_state" =>"$state",
//"x_zip" => "98004"
"x_zip" => "$zipcode"
//"x_market_type" => "2",
// "x_cpversion" => "1.0",
// "x_device_type"=>"7"
// Additional fields can be added here as outlined in the AIM integration
// guide at: http://developer.authorize.net
);
// This section takes the input fields and converts them to the proper format
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
$post_string = "";
foreach( $post_values as $key => $value )
{ $post_string .= "$key=" . urlencode( $value ) . "&"; }
$post_string = rtrim( $post_string, "& " );
// The following section provides an example of how to add line item details to
// the post string. Because line items may consist of multiple values with the
// same key/name, they cannot be simply added into the above array.
//
// This section is commented out by default.
/*
$line_items = array(
"item1<|>golf balls<|><|>2<|>18.95<|>Y",
"item2<|>golf bag<|>Wilson golf carry bag, red<|>1<|>39.99<|>Y",
"item3<|>book<|>Golf for Dummies<|>1<|>21.99<|>Y");
foreach( $line_items as $value )
{ $post_string .= "&x_line_item=" . urlencode( $value ); }
*/
// This sample code uses the CURL library for php to establish a connection,
// submit the post, and record the response.
// If you receive an error, you may want to ensure that you have the curl
// library enabled in your php configuration
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($request, CURLOPT_POSTFIELDS, $post_string); // use HTTP POST to send form data
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response.
$post_response = curl_exec($request); // execute curl post and store results in $post_response
//print_r($post_response); die;
// additional options may be required depending upon your server configuration
// you can find documentation on curl options at http://www.php.net/curl_setopt
curl_close ($request); // close curl object
$response_array = explode($post_values["x_delim_char"],$post_response);
print_r($response_array);die;
But the above code is giving the error "Can not accept payment from this market type".I have browse the net but not getting the solution.
What type of authorize.net account have you signed up for ? Retail or ECom ?
Retail accounts require card to be present during transaction
You are seeing this error because you accidentally signed up for a retail account instead of a card not present account. To fix this either sign up again for a card not present account or contact Authnet to have them change your account type for you.
Related
I am trying to make a php script to communicate with the indodax API endpoint. from the documentation provided there are some line that make me confused, namely in the following sentence: ( https://github.com/btcid/indodax-official-api-docs/blob/master/Private-RestAPI.md#withdraw-coin-endpoints )
"You also need to prepare a Callback URL. Callback URL is a URL that our system will call to verify your withdrawal requests. Various parameters will be sent to Callback URL, make sure to check this information on your server side. If all the data is correct, print out a string “ok” (without quotes). We will continue the request if only we receive “ok” (without quotes) response, otherwise the request will be failed."
Questions:
If I write a php script at https://www.ok.com/withdraw.php , then the URLCallback is https://www.ok.com/withdraw.php ? true or false ?
from the API document above :
"If all the data is correct, print out a string “ok” (without quotes). We will continue the request if only we receive “ok” (without quotes) response, otherwise the request will be failed."
what is "ok" (without quotes) response? does it have to be written in php script or not? if yes, please help me complete this code.
<?php
$url = 'https://indodax.com/tapi';
// Please find Key from trade API Indodax exchange
$key = '****';
// Please find Secret Key from trade API Indodax exchange
$secretKey = '****';
$data = [
'method' => 'withdrawCoin',
'timestamp' => '1578304294000',
'recvWindow' => '1578303937000',
'currency' => 'doge',
'withdraw_address' => 'D9iCdBLBosJzGSvpQGMSobwtdgB2rS1zam',
'withdraw_amount' => '10',
'withdraw_memo' => 'memo',
'request_id' => 'trx002'
];
$post_data = http_build_query($data, '', '&');
$sign = hash_hmac('sha512', $post_data, $secretKey);
$headers = ['Key:'.$key,'Sign:'.$sign];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => true
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
I've tried to make a php script as above with the api key and secret key ( https://github.com/btcid/indodax-official-api-docs/blob/master/example/Private-RestAPI-php.md#withdraw-coin ) . then the result is
"{"success":0,"error":"did not pass callback check","request_error":"","callback_response":"error code: 1020"}
"
I am trying to use the updateListing method to revise listing descriptions...
https://www.etsy.com/developers/documentation/reference/listing#method_updatelisting
I went through the OAuth Authentication process successfully and am able to make an authorized request via the API as per the example in the documentation. I am having problems with the updateListing method. I am trying to revise the description but get the following error…
“Invalid auth/bad request (got a 400, expected HTTP/1.1 20X or a redirect)Expected param 'quantity'.Array”
As per the documentation, the quantity is not required (and is actually depreciated for updateListing). When I use the existing quantity to populate ‘quantity’ in the array (commented out), it complains about another field it expects. I’m not sure why I’m getting an error regarding these fields as they are not required. I would not mind using the existing attributes available from my listing to populate these fields but there is a “shipping_template_id” field which I don’t currently have available. I can’t set it to null because it expects a numeric value. When I set it to 0, it says that it’s not a valid shipping template ID. I must be doing something wrong.
Here is my code (I replaced my actual token and token secrets)…
$access_token = "my token";
$access_token_secret = "my secret";
$oauth = new OAuth(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
$oauth->setToken($access_token, $access_token_secret);
try {
$url = "https://openapi.etsy.com/v2/private/listings";
$params = array('listing_id' => $result->listing_id,
//'quantity' => $result->quantity,
//'title' => $result->title,
'description' => $new_description);
$oauth->fetch($url, $params, OAUTH_HTTP_METHOD_POST);
$json = $oauth->getLastResponse();
print_r(json_decode($json, true));
}
catch (OAuthException $e) {
echo $e->getMessage();
echo $oauth->getLastResponse();
echo $oauth->getLastResponseInfo();
}
$args = array(
'data' => array(
"quantity" => $quantity,
"title" => $title,
"description" => strip_tags($description),
"price" => $price,
"materials" => $materials,
"shipping_template_id" =>(int)$shippingTemplateId,
"non_taxable" => false,
"state" => "$ced_etsy_upload_product_type",
"processing_min" => 1,
"processing_max" => 3,
"taxonomy_id" => (int)$categoryId,
"who_made" => $who_made,
"is_supply" => true,
"when_made" => $when_made,
)
);
Please try this may be this will help you.
I'm trying to use Paypal Mass Payment API with this code, but I got this error.
I saved this code to a file 'MassPay.php' and uploaded it to my localhost. I'm trying to test the code and if I can make it work I'll use it inside core php, to monthly mass pay teachers.
Array
(
[TIMESTAMP] => 2015-07-03T06:55:19Z
[CORRELATIONID] => 437cfd2eedc02
[ACK] => Failure
[VERSION] => 74.0
[BUILD] => 17235934
[L_ERRORCODE0] => 10004
[L_SHORTMESSAGE0] => Transaction refused because of an invalid argument. See additional error messages for details.
[L_LONGMESSAGE0] => The number of input records is less than or equal to zero
[L_SEVERITYCODE0] => Error
[ERRORS] => Array
(
[0] => Array
(
[L_ERRORCODE] => 10004
[L_SHORTMESSAGE] => Transaction refused because of an invalid argument. See additional error messages for details.
[L_LONGMESSAGE] => The number of input records is less than or equal to zero
[L_SEVERITYCODE] => Error
)
)
[REQUESTDATA] => Array
(
[USER] => dudhat-facilitator_api1.artoongames.com
[PWD] => AXAT8HSZRR4XANFZ
[VERSION] => 74.0
[BUTTONSOURCE] => AngellEYE_PHPClass
[SIGNATURE] => AFcWxV21C7fd0v3bYYYRCpSSRl31Ab1QV5bWA6uEZ.6emUAkZaZEhjiA
[METHOD] => MassPay
[EMAILSUBJECT] => dudhat#artoongames.com
[CURRENCYCODE] => USD
[RECEIVERTYPE] => EmailAddress
)
[RAWREQUEST] => USER=dudhat-facilitator_api1.artoongames.com&PWD=AXAT8HSZRR4XANFZ&VERSION=74.0&BUTTONSOURCE=AngellEYE_PHPClass&SIGNATURE=AFcWxV21C7fd0v3bYYYRCpSSRl31Ab1QV5bWA6uEZ.6emUAkZaZEhjiA&METHOD=MassPay&EMAILSUBJECT=dudhat%40artoongames.com&CURRENCYCODE=USD&RECEIVERTYPE=EmailAddress
[RAWRESPONSE] => TIMESTAMP=2015%2d07%2d03T06%3a55%3a19Z&CORRELATIONID=437cfd2eedc02&ACK=Failure&VERSION=74%2e0&BUILD=17235934&L_ERRORCODE0=10004&L_SHORTMESSAGE0=Transaction%20refused%20because%20of%20an%20invalid%20argument%2e%20See%20additional%20error%20messages%20for%20details%2e&L_LONGMESSAGE0=The%20number%20of%20input%20records%20is%20less%20than%20or%20equal%20to%20zero&L_SEVERITYCODE0=Error
)
Use this code "MassPay.php"
<?php
// Include required library files.
require_once('includes/config.php');
require_once('includes/paypal.class.php');
// Create PayPal object.
$PayPalConfig = array('Sandbox' => $sandbox, 'APIUsername' => $api_username, 'APIPassword' => $api_password, 'APISignature' => $api_signature);
$PayPal = new PayPal($PayPalConfig);
// Prepare request arrays
$MPFields = array(
'emailsubject' => 'dudhat#artoongames.com', // The subject line of the email that PayPal sends when the transaction is completed. Same for all recipients. 255 char max.
'currencycode' => 'USD', // Three-letter currency code.
'receivertype' => 'EmailAddress' // Indicates how you identify the recipients of payments in this call to MassPay. Must be EmailAddress or UserID
);
// Typically, you'll loop through some sort of records to build your MPItems array.
// Here I simply include 3 items individually.
$Item1 = array(
'l_email' => 'dudhat#gmail.com', // Required. Email address of recipient. You must specify either L_EMAIL or L_RECEIVERID but you must not mix the two.
'l_receiverid' => 'dudhat#gmail.com', // Required. ReceiverID of recipient. Must specify this or email address, but not both.
'l_amt' => '10.00', // Required. Payment amount.
'l_uniqueid' => '522', // Transaction-specific ID number for tracking in an accounting system.
'l_note' => 'test payment' // Custom note for each recipient.
);
$Item2 = array(
'l_email' => 'dilip#gmail.com', // Required. Email address of recipient. You must specify either L_EMAIL or L_RECEIVERID but you must not mix the two.
'l_receiverid' => 'dilip#gmail.com', // Required. ReceiverID of recipient. Must specify this or email address, but not both.
'l_amt' => '1.00', // Required. Payment amount.
'l_uniqueid' => '523', // Transaction-specific ID number for tracking in an accounting system.
'l_note' => 'test payment' // Custom note for each recipient.
);
$MPItems = array($Item1,$Item2); // etc
$PayPalRequestData = array('MPFields' => $MPFields, 'MPItems' => $MPFields);
// Pass data into class for processing with PayPal and load the response array into $PayPalResult
$PayPalResult = $PayPal->MassPay($PayPalRequestData);
// Write the contents of the response array to the screen for demo purposes.
echo '<pre />';
print_r($PayPalResult);
?>
You assembled some payment items in $MPItems, but did not add $MPItems into the PayPal request data. So PayPal rejected the mass payment as containing no payment items.
You can use below class for to make transaction of mass pay
define your constants with actual your credentials of paypal with mode(live/sandbox).
class PaypalnvpComponent {
private static $API_Username = PAYPAL_API_USERNAME;
private static $API_Password = PAYPAL_API_PASSWORD;
private static $API_Signature = PAYPAL_API_SIGNATURE;
private static $API_Environment = PAYPAL_API_MODE;
private static $API_Version = '116.0';
public static function Call($methodName,$params){
if(self::$API_Environment == 'LIVE'){
$API_Endpoint = "https://api-3t.paypal.com/nvp";
}else{
$API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
}
$nvpstr = "";
foreach($params as $k=>$v){
$nvpstr .="&".$k."=".urlencode($v);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
//Turn of server and pakagemanager
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
//set the API operation,version,API signature in requrest
$nvpreq ="";
$nvpreq .= "METHOD=".urlencode($methodName);
$nvpreq .= "&VERSION=".urlencode(self::$API_Version);
$nvpreq .= "&PWD=".urlencode(self::$API_Password);
$nvpreq .= "&USER=".urlencode(self::$API_Username);
$nvpreq .= "&SIGNATURE=".urlencode(self::$API_Signature);
$nvpreq .= $nvpstr;
//set the request as POST field for curl
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
//get the response from server
$httpResponse = curl_exec($ch);
if(!$httpResponse){
return "$methodName failed:".curl_error($ch).'('.curl_errno($ch).')';
}
//Extract the response details
$httpResponseArray = explode('&', $httpResponse);
$httpParsedResponseArray = array();
foreach ($httpResponseArray as $i=>$value){
$tmpArray = explode('=', $value);
if(sizeof($tmpArray) > 1){
$httpParsedResponseArray[$tmpArray[0]] = urldecode($tmpArray[1]);
}
}
if((0 == sizeof($httpParsedResponseArray)) || !array_key_exists('ACK',$httpParsedResponseArray)){
return "Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.";
}
return $httpParsedResponseArray;
}
#----------------------------
# #$hok
# mass payment with multiple users in one go
# paypal transaction status will be : Completed, Failed, Returned, Reversed, Unclaimed, Pending, Blocked
#----------------------------
public static function MassPay($params){
$methodName = "MassPay";
return self::Call($methodName, $params);
}
public static function GetTransactionDetail($params){
$methodName = "GetTransactionDetails";
return self::Call($methodName, $params);
}
public static function TransactionSearch($params){
$methodName = "TransactionSearch";
return self::Call($methodName, $params);
}
}
# below is the example how to use above class
$params = array();
$params["RECEIVERTYPE"] = "EmailAddress";
$params["EMAILSUBJECT"] = "Your withdraw request was processed";
$params["L_AMT0"] = 1;
$params["L_EMAIL0"] = "xyz#xyz.abc";
$params["L_UNIQUEID0"] = rand(11111,9999999);
$params["L_AMT1"] = 2;
$params["L_EMAIL1"] = "hamed-buyer#lifeofu.com";
$params["L_UNIQUEID1"] = rand(11111,9999999);
$params["L_AMT2"] = 3;
$params["L_EMAIL2"] = "testuser1#test1.com";
$params["L_UNIQUEID2"] = rand(11111,9999999);
$params["CURRENCYCODE"] = "USD";
$result = PaypalnvpComponent::MassPay($params);
//transaction detial
$params = array();
$params["TRANSACTIONID"] = TRANSACTIONID_HERE;
$result = PaypalnvpComponent::GetTransactionDetail($params);
I've started with importing contacts from live. Now I don't know what MS is thinking, but they seriously do overcomplicate everything they put their hands to.
For my app, it's very important that I get a phone number. So important in fact, that should you not have a phone number, your contact is skipped. With my method I can't see any phone numbers. I assumed that it would be shown if I loop through each contact one by one, but alas, no love.
Here is my method:
$import_id = time();
$client_id = "xxx";
$redirect_uri = 'redirecturi';
$client_secret = "xxx";
$code = $_GET['code'];
$grant_type = "authorization_code";
$post = "client_id=$client_id&redirect_uri=$redirect_uri&client_secret=$client_secret&code=$code&grant_type=$grant_type";
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,"https://login.live.com/oauth20_token.srf");
curl_setopt($curl,CURLOPT_POST,5);
curl_setopt($curl,CURLOPT_POSTFIELDS,$post);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
$result = curl_exec($curl);
curl_close($curl);
$token = json_decode($result);
$access_token = $token->access_token;
$user_id = $token->user_id;
$url = "https://apis.live.net/v5.0/me/contacts?access_token=$access_token";
$response = curl_file_get_contents($url);
$response = json_decode($response);
foreach($response->data as $contact) {
$contact_details = curl_file_get_contents("https://apis.live.net/v5.0/" . $contact->id . "?access_token=$access_token");
debug($contact_details);
}
die();
However, I'm only getting info back like this (this person I know has a contact number as I can see it when I view him on people.live.com):
{
"id": "contact.id",
"first_name": "Danie",
"last_name": "Van den Heever",
"name": "Danie Van den Heever",
"is_friend": false,
"is_favorite": false,
"user_id": "userid",
"email_hashes": [
"emailhash"
],
"updated_time": "2014-09-17T12:11:10+0000"
}
My permission request url (which defines the scopes) looks like this:
https://login.live.com/oauth20_authorize.srf?client_id=clientidkey&scope=wl.basic%20wl.offline_access&response_type=code&redirect_uri=redirecturi
Should I add more scopes to get the contact number? If so, which scopes? Or is this not possible?
The solution is to use an undocumented scope wl.contacts_phone_numbers, there is a risk that it'll become deprecated or just locked down and only Microsoft-approved clients will be able to use it, but in the meantime it works.
Also you do not need to do an extra request for every contact, the contact object you get from me/contacts already has the phone numbers in a phones object.
By the way, here's the code I used while testing this, I used a REST client library which avoids copy/pasting the long and repetitive cURL parameters each time and turns the requests into one-liners.
Code to ask for permission :
$params = ["client_id" => "...", "scope" => "wl.basic wl.contacts_phone_numbers", "response_type" => "code", "redirect_uri" => "http://sanctuary/contacts_callback.php"];
header("Location: https://login.live.com/oauth20_authorize.srf?".http_build_query($params));
Note the extra wl.contacts_phone_numbers scope in the permission request.
Code to get access token and retrieve contacts :
// Composer's autoloader, required to load libraries installed with it
// in this case it's the REST client
require "vendor/autoload.php";
// exchange the temporary token for a reusable access token
$resp = GuzzleHttp\post("https://login.live.com/oauth20_token.srf", ["body" => ["client_id" => "...", "client_secret" => "...", "code" => $_GET["code"], "redirect_uri" => "http://sanctuary/contacts_callback.php", "grant_type" => "authorization_code"]])->json();
$token = $resp["access_token"];
// REST client object that will send the access token by default
// avoids writing the absolute URL and the token each time
$client = new GuzzleHttp\Client(["base_url" => "https://apis.live.net/v5.0/", "defaults" => ["query" => ["access_token" => $token]]]);
// get all the user's contacts
$contacts = $client->get("me/contacts")->json()["data"];
// iterate over contacts
foreach ($contacts as $contact) {
// if that contact has a phone number object
if (array_key_exists("phones", $contact)) {
// iterate over each phone number
foreach ($contact["phones"] as $phone) {
// if number isn't blank
if (!empty($phone)) {
// do whatever you want with that number
}
}
}
}
Here's what me/contacts looks like with the extra scope (minus a few line breaks and personal info) :
Array (
[data] => Array (
[0] => Array (
[id] => contact...
[first_name] => ...
[last_name] => ...
[name] => ...
[is_friend] =>
[is_favorite] =>
[user_id] =>
[email_hashes] => ...
[updated_time] => ...
[phones] => Array ( // what you asked for
[personal] =>
[business] =>
[mobile] => +337...
)
)
)
)
From reading the documentation, phone numbers are part of the User object.
To fetch their phone numbers, you would;
Grab a list of their contacts (which you've done)
Iterate through the result set
Grab the user id from the contact response. (Key id)
Make a request to the User collection (with the wl.phone_numbers scope)
See if the phone numbers are null or not
If they are NULL, skip the iteration
An example phones object (in the User response);
"phones": {
"personal": "(555) 555-1212",
"business": "(555) 111-1212",
"mobile": null
}
So;
$arrUser = json_decode($strResponse, true);
if( is_null($arrUser['phones']['personal'])
AND is_null($arrUser['phones']['business']
AND is_null($arrUser['phones']['mobile']) ) {
//No phone numbers
//Assuming you're in a loop, fetching a user object for each contact - skip the iteration & move onto the next contact.
continue;
}
I'm trying to post a new item to a listing website using LWP. The listing website provides an example of how to post the data but using PHP, I’ve therefore tried to reproduce the solution but in Perl.
This is the PHP example.
$postData = array('type' => 'fixedPrice',
'item' => array(
'id_country' => 0,
'id_category' => 80,
'fixed_price' => '1.00',
'currency' => 'EUR',
'title' => 'My title',
'personal_reference' => 'My personal ref',
));
//RESOURCE CALL WITH POST METHOD
$url = 'http://correct.server.address/item?token=MyPersonalToken';
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($postData) );
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$xml_response = curl_exec($ch);
My Perl solution:
#!/usr/bin/perl
### Module requests ###
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common;
use XML::LibXML;
use Data::Dumper;
### Make Request to get the session Token ###
my $url = "http://correct.server.address/seller";
my $api = "APIKEY";
my $userAgent = LWP::UserAgent->new();
my $request = HTTP::Request->new(POST => $url . "?apikey=" . $api);
my $response = $userAgent->request($request);
### Display error if request to server fails ###
unless ($response->is_success) {
print "Content-type: text/html\n\n";
print "Error: " . $response->status_line;
exit;
}
### Assign response xml to $xml_token ###
my $xml_token = $response->content;
### Parse XML through XML::LibXML module ###
my $parser = XML::LibXML->new();
my $tree = $parser->parse_string($xml_token);
my $root = $tree->getDocumentElement;
my $token = $root->getElementsByTagName('token');
### Make Request to add Item - PROBLEM STARTS HERE ###
my $postURL = "http://correct.server.address/item" . "?token=" . $token;
my %item_data = (type => "fixedPrice",
item => {
id_country => "0",
id_category => "728",
fixed_price => "1.00",
currency => "GBP",
title => "Test item",
personal_reference => "12345"
}
);
my $userAgentReq2 = LWP::UserAgent->new();
my $requestReq2 = HTTP::Request->new(POST => $postURL);
$requestReq2->header(content_type => 'multipart/form-data');
$requestReq2->content(\%item_data);
my $responseReq2 = $userAgentReq2->request($requestReq2);
### Display error if request to server fails ###
unless ($responseReq2->is_success) {
print "Content-type: text/html\n\n";
print "<p>Error Message: " . $responseReq2->status_line;
print "</p><p>Output of test data sent: \n";
print Dumper(\%item_data);
print "</p><p>Dumped Response: \n";
print Dumper($responseReq2);
print "</p><p>\n";
print "Token: $token\n";
print "</p><p>\n";
print "Response: " . $responseReq2->as_string;
print "</p>\n";
exit;
}
### Assign response xml to $xml_responseReq2 ###
my $xml_responseReq2 = $responseReq2->content;
### Display Token ###
print "Content-type: text/html\n\n";
print "<p>Response: $xml_responseReq2</p>\n";
print Dumper($responseReq2);
exit;
My first post request to retrieve the session token works correctly and I receive the token. However my second post request trying to add the item fails.
This is the dumped response:
$VAR1 = bless( {
'_content' => 'Not a SCALAR reference at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 203.
',
'_rc' => 500,
'_headers' => bless( {
'client-warning' => 'Internal response',
'client-date' => 'Fri, 21 Mar 2014 12:13:34 GMT',
'content-type' => 'text/plain',
'::std_case' => {
'client-warning' => 'Client-Warning',
'client-date' => 'Client-Date'
}
}, 'HTTP::Headers' ),
'_msg' => 'Not a SCALAR reference',
'_request' => bless( {
'_content' => {
'item' => {
'currency' => 'GBP',
'id_category' => '728',
'id_country' => '0',
'personal_reference' => '12345',
'title' => 'Test item',
'fixed_price' => '1.00'
},
'type' => 'fixedPrice'
},
'_uri' => bless( do{\(my $o = 'http://correct.server.address/item?token=986aee823d54a7c2d50651c1b272c455')}, 'URI::http' ),
'_headers' => bless( {
'user-agent' => 'libwww-perl/6.05',
'content-type' => 'multipart/form-data'
}, 'HTTP::Headers' ),
'_method' => 'POST'
}, 'HTTP::Request' )
}, 'HTTP::Response' );
Please can someone help me as to where I’m going wrong, many thanks in advance!
The following appears to achieve what you want.
my %item_data = (type => "fixedPrice",
'item[id_country]' => "0",
'item[id_category]' => "728",
'item[fixed_price]' => "1.00",
'item[currency]' => "GBP",
'item[title]' => "Test item",
'item[personal_reference]' => "12345"
);
my $userAgentReq2 = LWP::UserAgent->new();
my $responseReq2 = $userAgentReq2->post($postURL,[%item_data]);
PHP allows you to create POST variables that get automatically deserialized into nested structures; for example, you can have form fields called item[0] and item[1] and so forth and those will appear in your server-side PHP script as an array of values. But HTTP does not have any concept of arrays; post data are simple key and value pairs.
The sample client-side PHP code is trying to build a nested array structure which PHP's curl interface will automatically translate into HTTP field names. It's been a million years since I've done any PHP, but I think the field names would end up being item[0][id_country], item[0][id_category], and so on. This is how PHP "cheats" HTTP to put complex structure into POSTs.
Perl's LWP library does not support building field names out of nested structures this way. That's why you're getting this error:
Not a SCALAR reference at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 203.
'
In your POST arguments, the item key is pointing to a hash reference, but LWP expects to only see a plain scalar or scalar reference there.
So you'll need to change your LWP POST parameters to something like the following. (If this is not exactly right, you can use a HTTP sniffer on the PHP code to figure out what the actual field names are that it generates.)
my %item_data = (type => "fixedPrice",
'item[0][id_country]' => "0",
'item[0][id_category]' => "728",
'item[0][fixed_price]' => "1.00",
'item[0][currency]' => "GBP",
'item[0][title]' => "Test item",
'item[0][personal_reference]' => "12345"
);