1

我正在尝试使用 CURL PHP 获取沃尔玛卖家 API 来确认。任何人都可以建议我需要使用哪个 RSA PHP 库吗?以便在调用 walmart 时验证身份验证签名。

有这方面的经验吗?

$headers = array(
    'WM_SVC.NAME: Walmart Marketplace',
    'WM_QOS.CORRELATION_ID: 14730688612',
    'WM_SEC.TIMESTAMP:14730688612',
    'WM_SEC.AUTH_SIGNATURE: XXXXXXXXXXX'
    'WM_CONSUMER.ID: XXXXXXXXXXX',
    'Content-Type: application/xml',
    'Accept: application/xml',
 );


$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL,$requestUrl);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec( $ch );
if(curl_errno($ch)):
    echo 'Curl error: '.curl_error($ch);
endif;

我使用了谷歌搜索时发现的参考资料。

 - https://github.com/fillup/walmart-auth-signature-php
4

4 回答 4

1

In the new API after August of 2018, you have to generate an access token AND then use a completely separate authentication header to pull anything from their API. It took a couple of hours just to figure this out, so I hope this helps someone in the future.

(This is for the Marketplace API, but should work for any Walmart API)

To generate the access token, you have to pass these headers:

Array(
[0] => Authorization: Basic BASE64_ENCODED_VARIABLE (see below)
[1] => Content-Type: application/x-www-form-urlencoded
[2] => Accept: application/json
[3] => WM_SVC.NAME: Walmart Marketplace
[4] => WM_QOS.CORRELATION_ID: 10_DIGIT_RANDOM_GENERATED_ALPHANUMERIC_ID
[5] => WM_SVC.VERSION: 1.0.0
[6] => WM_CONSUMER.CHANNEL.TYPE: PROVIDED_WHEN_GENERATING_CLIENT_ID_AND_SECRET
)

To generate BASE64_ENCODED_VARIABLE, create a variable using base64_encode as such:

$auth = base64_encode($clientId . ":" . $clientSecret);

...where Client ID and Client Secret are generated from Wal-Mart's Developer Portal API area.

===========================================

After you successfully POST that data to Walmart and receive an Access Token in return, you want to pass the following headers in ANY API CALL you make with Wal-Mart:

Array(
[0] => Authorization: Basic BASE64_ENCODED_VARIABLE (as described above)
[1] => WM_SVC.NAME: Walmart Marketplace
[2] => WM_QOS.CORRELATION_ID: 10_DIGIT_RANDOM_GENERATED_ALPHANUMERIC_ID
[3] => WM_CONSUMER.CHANNEL.TYPE: PROVIDED_WHEN_GENERATING_CLIENT_ID_AND_SECRET
[4] => WM_SEC.ACCESS_TOKEN: GENERATED_FROM_PREVIOUS_STEP (returned as [access_token])
[5] => Content-Type: application/json
[6] => Accept: application/json
)

...then make your calls.

This is what FINALLY worked for me after continuously receiving UNAUTHORIZED.GMP_GATEWAY_API errors across the board.

Passing "Authorization: Bearer TOKENTOKENTOKEN" instead of the way I've listed above WILL NOT WORK as the authentication header. Trust me :-)

于 2020-04-08T02:59:55.947 回答
1

最困难的部分是生成签名并使其正常工作。

我从不同的地方提取了很多这样的片段来给出一个直接的例子,所以希望它会起作用。

假设我们要进行 GET 调用以获取我们所有的提要状态。

// Your walmart info from walmart admin
$walmart_consuer_id = XXXXXXXXXXXXX;
$walmart_channel_type = XXXXXXXXXXXX;

$request_type = "GET";

$url = "https://marketplace.walmartapis.com/v2/feeds";

// We need a timestamp to generate the signature and to send as part of the header
$timestamp = round(microtime(true) * 1000);

$signature = getClientSignature($url, $request_type, $timestamp);

$headers = array();
$headers[] = "Accept: application/xml";
$headers[] = "WM_SVC.NAME: Walmart Marketplace";
$headers[] = "WM_CONSUMER.ID: ".$walmart_consuer_id;
$headers[] = "WM_SEC.TIMESTAMP: ".$timestamp;
$headers[] = "WM_SEC.AUTH_SIGNATURE: ".$signature;
$headers[] = "WM_QOS.CORRELATION_ID: ".mt_rand();
$headers[] = "WM_CONSUMER.CHANNEL.TYPE: " .$walmart_channel_type;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_type);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);

function getClientSignature($url, $request_type, $timestamp) {
  // Your walmart info from walmart admin
  $walmart_secret = XXXXXXXXXXXXXXXX;
  $walmart_consuer_id = XXXXXXXXXXXXX;

  // Get an openssl usable private key from the walmart supplied secret
  $pem = pkcs8_to_pem(base64_decode($walmart_secret));
  $private_key = openssl_pkey_get_private($pem);

  // Construct the data we want to sign
  $data = $walmart_consuer_id."\n";
  $data .= $url."\n";
  $data .= $request_type."\n";
  $data .= $timestamp."\n";

  // Sign the data
  $hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256";
  if (!openssl_sign($data, $signature, $private_key, $hash)) {
    // ERROR
    return null;
  }

  return base64_encode($signature);
}

function pkcs8_to_pem($der) {

  static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----";
  static $END_MARKER = "-----END PRIVATE KEY-----";

  $value = base64_encode($der);

  $pem = $BEGIN_MARKER . "\n";
  $pem .= chunk_split($value, 64, "\n");
  $pem .= $END_MARKER . "\n";

  return $pem;
}
于 2016-10-28T16:01:42.390 回答
0
<?php
$consumer_id='xxxxxxxxxx';
$private_key='xxxxxxxxxx';
$timestamp='xxxxxxxx';
$correlation_id='xxxxxxxxxxx';
$channel_id='xxxxxxxxxx';

$endPoint = "v3/feeds?feedType=item";
$requestUrl = "https://marketplace.walmartapis.com/$endPoint";
$requestMethod = 'POST';
$signature = new Signature($consumer_id, $private_key, $requestUrl,       $requestMethod);
$actual_signature = $signature->getSignature($timestamp);

$file = '..../walmart_product.xml';

$headers = [];
$headers[] = "WM_SVC.NAME: Walmart Marketplace";
$headers[] = "WM_QOS.CORRELATION_ID: ".$correlation_id;
$headers[] = "WM_SEC.TIMESTAMP: ".$timestamp;
$headers[] = "WM_SEC.AUTH_SIGNATURE: ".$actual_signature;
$headers[] = "WM_CONSUMER.ID: " .$consumer_id;
$headers[] = "Content-Type: multipart/form-data";
$headers[] = "Accept: application/xml";
$headers[] = "WM_CONSUMER.CHANNEL.TYPE: ".$channel_id;
$headers[] = "HOST: marketplace.walmartapis.com";


$body ['file'] = new \CurlFile ( $file, 'application/xml' );

$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $requestUrl );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $body );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
$server_output = curl_exec ( $ch );
?>
于 2017-11-23T13:09:16.400 回答
-1
$ch = curl_init();

$headers = $actual;

$qos = uniqid();

$url='https://api-gateway.walmart.com/v3/items';

$options = 
array (
    CURLOPT_URL => $url,

    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_TIMEOUT => 60,

    CURLOPT_HEADER => false,

    CURLOPT_POST => 1,

    CURLOPT_HTTPHEADER => array(
    'WM_SVC.NAME: Drop Ship Vendor Services',

    'WM_QOS.CORRELATION_ID:'.$qos,

    'WM_SEC.TIMESTAMP:1451606400',

    'WM_SEC.AUTH_SIGNATURE: '.$headers,

    'WM_CONSUMER.ID:'.$WalmartConsumerID
,
    'WM_CONSUMER.CHANNEL.TYPE:**********',

    'Accept: application/xml'
        ),

    CURLOPT_HTTPGET => true
);

curl_setopt_array($ch, $options);

$response = curl_exec ($ch);

print_r($response);
于 2017-11-10T10:00:54.717 回答