php - Cybersource SOAP API के लिए Savon अनुरोध को कैसे प्रारूपित करें
ruby-on-rails ruby (1)
सावन और रूबी का उपयोग करके साइबरसोर्स भुगतान के लिए अनुरोध को प्रारूपित करने का तरीका जानने का प्रयास करना।
मैं थोड़ी देर के लिए इस पर रहा हूं, बिना किस्मत के। मैं अनुरोध प्राप्त कर रहा हूं मैसेज समर्थित नहीं है
मैं अनुमान लगा रहा हूं कि मैं संदेश निकाय के पैरामीटर में कैसे गुजर रहा हूं, और / या हेडर सही तरीके से सेटअप नहीं हो रहा है।
एसओएपी एपीआई के लिए अपेक्षित एक्सएमएल है:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>yourMerchantID</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">yourPassword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<requestMessage xmlns="urn:schemas-cybersource-com:transaction-data-N.NN">
<merchantID>yourMerchantID</merchantID>
<merchantReferenceCode>MRC-123</merchantReferenceCode>
<billTo>
<firstName>John</firstName>
<lastName>Doe</lastName>
<street1>1295 Charleston Road</street1>
<city>Mountain View</city>
<state>CA</state>
<postalCode>94043</postalCode>
<country>US</country>
<email>[email protected]</email>
</billTo>
<item id="0">
<unitPrice>5.00</unitPrice>
<quantity>1</quantity>
</item>
<item id="1">
<unitPrice>10.00</unitPrice>
<quantity>2</quantity>
</item>
<purchaseTotals>
<currency>USD</currency>
</purchaseTotals>
<card>
<accountNumber>4111111111111111</accountNumber>
<expirationMonth>11</expirationMonth>
<expirationYear>2020</expirationYear>
</card>
<ccAuthService run="true" />
</requestMessage>
</soapenv:Body>
</soapenv:Envelope>
यह एक्सएमएल है जो मैं अनुरोध करने का प्रयास करते समय प्राप्त कर रहा हूं।
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:data="urn:schemas-cybersource-com:transaction-data:TransactionProcessor" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
<wsse:Username>GiveCampusCDW</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">ju12trzJpnO81ZwSxPdy5htTVeOyUmICDWNmWjXuimTx9Qy+myOB4B4G8ItiJdfu37pJ6jJO2OAmCDIAoWjlgeMO5mvlYxKkVAoDEi2b2dxwLzJlkjUhhyznNzbz71b96lFRgoHGO2YpSlmT5VzTATNVt6SBUVV+iG3D3nndMwAPOmw5M+jSwP0xubZGYPV9bvuCFXI/GcNTsQYN9DWinqMjmq5zw13VgSObQFTPTn5iR+wGcOaj+1fK7IJjYlz82uRF0RHK7JTt0UIDsxULarEiJZBs+VFq9LjPblWI28365bHFs7ooNrgYJkVz+byCaswTj1wWeUecOX3L452zsQ==</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<env:Body>
<data:requestMessage xmlns="urn:schemas-cybersource-com:transaction-data-1.129">
<merchantID>GiveCampusCDW</merchantID>
<merchantReferenceCode>ContributionID</merchantReferenceCode>
<billTo>
<firstName>Saul</firstName>
<lastName>Goodman</lastName>
<street1>1295 Charleston Road</street1>
<city>Mountain View</city>
<state>CA</state>
<postalCode>94043</postalCode>
<country>US</country>
<email>[email protected]</email>
</billTo>
<item>
<unitPrice>50.00</unitPrice>
<quantity>1</quantity>
</item>
<purchaseTotals>
<currency>USD</currency>
</purchaseTotals>
<card>
<accountNumber>4111111111111111</accountNumber>
<expirationMonth>12</expirationMonth>
<expirationYear>2020</expirationYear>
</card>
<ccAuthService>
<run>true</run>
</ccAuthService>
</data:requestMessage>
</env:Body>
</env:Envelope>
यह वह त्रुटि है जो वापस आती है:
ybersource::SoapException ((soap:Client)
Element (urn:schemas-cybersource-com:transaction-data:TransactionProcessor):requestMessage not supported.
):
lib/cybersource/client.rb:73:in `rescue in run_transaction'
lib/cybersource/client.rb:38:in `run_transaction'
app/controllers/transactions_controller.rb:7:in `new'
यहां मेरी रूबी क्लास है, जो इसे सब कुछ लपेटने और कॉल करने के लिए उपयोग की जाती है।
module Cybersource
class Client
attr_reader :merchant_id, :transaction_key
def initialize(merchant_id, transaction_key)
@merchant_id = merchant_id
@transaction_key = transaction_key
end
def client
# set the header which includes the merchant_id and transaction_key
soap_header = <<-HEREDOC
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Security SOAP-ENV:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>#{@merchant_id}</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">#{@transaction_key}</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
HEREDOC
# initialize a Savon client
Savon.client(
env_namespace: 'soapenv',
#namespace: "urn:schemas-cybersource-com:transaction-data:TransactionProcessor",
soap_header: soap_header,
#endpoint: "http://ics2wstest.ic3.com",
wsdl: "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.129.wsdl",
pretty_print_xml: true,
logger: Rails.logger,
log: true
)
end
def run_transaction
# build up the xml message passed to the web service
message = {
merchantID: @merchant_id,
merchantReferenceCode: rand(100),
billTo: {
firstName: "Saul",
lastName: "Goodman",
street1: "1295 Charleston Road",
city: "Mountain View",
state: "CA",
postalCode: "94043",
country: "US",
email: "[email protected]",
},
item: {
unitPrice: "50.00",
quantity: "1",
},
purchaseTotals: {
currency: "USD"
},
card: {
accountNumber: "4111111111111111",
expirationMonth: "12",
expirationYear: "2020"
},
ccAuthService: {run: "true"},
}
response = client.call(:run_transaction, message: message, :attributes => {
# sets the xmlns on the requestMessage tag
'xmlns' => 'urn:schemas-cybersource-com:transaction-data-1.129',
})
# return the response body
response.body[:response]
rescue Savon::SOAPFault => error
raise Cybersource::SoapException, error
end
protected
def wsdl_url
if Rails.env.production?
ENV["CYBERSOURCE_LIVE_WSDL_URL"]
else
ENV["CYBERSOURCE_TEST_WSDL_URL"]
end
end
end
end
मुझे केवल एक PHP कोड उदाहरण मिल गया है, लेकिन मुझे यकीन नहीं है कि इसे रूबी में कैसे परिवर्तित किया जाए।
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" content="text/html; charset=iso-8859-1">
<TITLE>Order Status</TITLE>
</HEAD>
<BODY>
<?php
// Before using this example, replace the generic values with your merchant ID and password.
define( 'MERCHANT_ID', 'your_merchant_id' );
define( 'TRANSACTION_KEY', 'your_transaction_key' );
define( 'WSDL_URL', 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.26.wsdl' );
class ExtendedClient extends SoapClient {
function __construct($wsdl, $options = null) {
parent::__construct($wsdl, $options);
}
// This section inserts the UsernameToken information in the outgoing SOAP message.
function __doRequest($request, $location, $action, $version) {
$user = MERCHANT_ID;
$password = TRANSACTION_KEY;
$soapHeader = "<SOAP-ENV:Header xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"><wsse:Security SOAP-ENV:mustUnderstand=\"1\"><wsse:UsernameToken><wsse:Username>$user</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">$password</wsse:Password></wsse:UsernameToken></wsse:Security></SOAP-ENV:Header>";
$requestDOM = new DOMDocument('1.0');
$soapHeaderDOM = new DOMDocument('1.0');
try {
$requestDOM->loadXML($request);
$soapHeaderDOM->loadXML($soapHeader);
$node = $requestDOM->importNode($soapHeaderDOM->firstChild, true);
$requestDOM->firstChild->insertBefore(
$node, $requestDOM->firstChild->firstChild);
$request = $requestDOM->saveXML();
// printf( "Modified Request:\n*$request*\n" );
} catch (DOMException $e) {
die( 'Error adding UsernameToken: ' . $e->code);
}
return parent::__doRequest($request, $location, $action, $version);
}
}
try {
$soapClient = new ExtendedClient(WSDL_URL, array());
/*
To see the functions and types that the SOAP extension can automatically
generate from the WSDL file, uncomment this section:
$functions = $soapClient->__getFunctions();
print_r($functions);
$types = $soapClient->__getTypes();
print_r($types);
*/
$request = new stdClass();
$request->merchantID = MERCHANT_ID;
// Before using this example, replace the generic value with your own.
$request->merchantReferenceCode = "your_merchant_reference_code";
// To help us troubleshoot any problems that you may encounter,
// please include the following information about your PHP application.
$request->clientLibrary = "PHP";
$request->clientLibraryVersion = phpversion();
$request->clientEnvironment = php_uname();
// This section contains a sample transaction request for the authorization
// service with complete billing, payment card, and purchase (two items) information.
$ccAuthService = new stdClass();
$ccAuthService->run = "true";
$request->ccAuthService = $ccAuthService;
$billTo = new stdClass();
$billTo->firstName = "John";
$billTo->lastName = "Doe";
$billTo->street1 = "1295 Charleston Road";
$billTo->city = "Mountain View";
$billTo->state = "CA";
$billTo->postalCode = "94043";
$billTo->country = "US";
$billTo->email = "[email protected]";
$billTo->ipAddress = "10.7.111.111";
$request->billTo = $billTo;
$card = new stdClass();
$card->accountNumber = "4111111111111111";
$card->expirationMonth = "12";
$card->expirationYear = "2020";
$request->card = $card;
$purchaseTotals = new stdClass();
$purchaseTotals->currency = "USD";
$request->purchaseTotals = $purchaseTotals;
$item0 = new stdClass();
$item0->unitPrice = "12.34";
$item0->quantity = "2";
$item0->id = "0";
$item1 = new stdClass();
$item1->unitPrice = "56.78";
$item1->id = "1";
$request->item = array($item0, $item1);
$reply = $soapClient->runTransaction($request);
// This section will show all the reply fields.
// var_dump($reply);
// To retrieve individual reply fields, follow these examples.
printf( "decision = $reply->decision<br>" );
printf( "reasonCode = $reply->reasonCode<br>" );
printf( "requestID = $reply->requestID<br>" );
printf( "requestToken = $reply->requestToken<br>" );
printf( "ccAuthReply->reasonCode = " . $reply->ccAuthReply->reasonCode . "<br>");
} catch (SoapFault $exception) {
var_dump(get_class($exception));
var_dump($exception);
}
?>
</BODY>
</HTML>
कोई भी सहायताकाफी प्रशंसनीय होगी।
सबसे पहले मुझे कहना है कि रूबी का मेरा ज्ञान कम है, इसलिए मैं सावन क्लाइंट के साथ मदद नहीं कर सकता। लेकिन मैंने आपके कच्चे एक्सएमएल अनुरोध का प्रयास किया, और महसूस किया कि ठीक से अनुरोध गलत नामस्थान में समाप्त हो गया है:
<data:requestMessage>
xmlns:data="urn:schemas-cybersource-com:transaction-data:TransactionProcessor"
को संदर्भित करता है xmlns:data="urn:schemas-cybersource-com:transaction-data:TransactionProcessor"
जब यह xmlns:data="urn:schemas-cybersource-com:transaction-data-1.129"
होना चाहिए xmlns:data="urn:schemas-cybersource-com:transaction-data-1.129"
मैंने देखा है कि आपने अपने क्लाइंट प्रारंभिकरण में नेमस्पेस पैरामीटर पर टिप्पणी की है। यदि ग्राहक इसे wsdl से नहीं पढ़ता है तो नामस्थान सेट करने का यह तरीका हो सकता है।
इस उत्तर के अनुसार आप आवश्यकतानुसार अलग-अलग नामस्थान निर्दिष्ट कर सकते हैं।
अद्यतन करें
ठीक है, मुझे लगता है कि मुझे यह काम करने के लिए मिला है। इस स्क्रिप्ट पर एक नज़र डालें:
require 'savon'
soap_header = <<-HEREDOC
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">transaction_key</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
HEREDOC
client = Savon.client(
wsdl: 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.129.wsdl',
soap_header: soap_header,
env_namespace: 'soapenv',
element_form_default: :unqualified,
namespace: "urn:schemas-cybersource-com:transaction-data-1.129",
namespaces: {
"xmlns:wsse": "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
},
pretty_print_xml: true,
#logger: Rails.logger,
log: true
)
message = {
merchantID: "merch_id",
merchantReferenceCode: rand(100),
billTo: {
firstName: "Saul",
lastName: "Goodman",
street1: "1295 Charleston Road",
city: "Mountain View",
state: "CA",
postalCode: "94043",
country: "US",
email: "[email protected]",
},
item: {
unitPrice: "50.00",
quantity: "1",
},
purchaseTotals: {
currency: "USD"
},
card: {
accountNumber: "4111111111111111",
expirationMonth: "12",
expirationYear: "2020"
},
ccAuthService: {
:@run => "true"
}
}
response = client.call(:run_transaction, message: message, :attributes => {
'xmlns' => 'urn:schemas-cybersource-com:transaction-data-1.129',
})
response.body[:response]
इसके साथ मैं उम्मीद के रूप में प्रमाणीकरण विफल हो रहा है। तो, कुछ चीजें जो गलत थीं:
हेडर परिभाषा को
Header
नोड छोड़ना चाहिए, बस आंतरिक नोड्स (Security
) से शुरू करेंccAuthService
run => true
ccAuthService
मेंrun => true
एक विशेषता है, न कि आंतरिक नोड।requestMessage
की पूरी नेमस्पेसिंग गड़बड़।