Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

php - Paypal Customer Dispute API - Provide Evidence always returns MISSING_OR_INVALID_REQUEST_BODY

I've been trying to upload a pdf file when providing an evidence to Paypal Disputes in the Claim Stage after verifying that the dispute case has the /provide-evidence on its HATEOAS links, the curl code below works in the CLI:

 $ curl -v -X POST https://api.sandbox.paypal.com/v1/customer/disputes/PP-D-12345/provide-evidence 
   -H "Content-Type: multipart/related" 
   -H "Authorization: Bearer {AccessToken}" 
   -F 'input={"evidences":[{"evidence_type": "PROOF_OF_FULFILLMENT", "evidence_info": {"tracking_info": [{"carrier_name": "FEDEX", "tracking_number": "123456789"}]}, "notes": "Test"}]};type=application/json' 
   -F 'file1=@D:Samplestorageapppaypalsample.pdf'

However when converted to PHP, either using curl or guzzle the API returns VALIDATION_ERROR - MISSING_OR_INVALID_REQUEST_BODY, I've tried almost every possible approach, but the error is consistent.

Using Guzzle: (trying to copy the working curl above as much as possible, since Guzzle can't send multipart/related request, I had to modify the content-type manually).

$pdf = 'D:Samplestorageapppaypalsample.pdf';

$input = [
  'evidences' => [
    [
      'evidence_type' => 'PROOF_OF_FULFILLMENT',
      'evidence_info' => [
        'tracking_info' => [
          'carrier_name' => "FEDEX",
          'tracking_number' => '122533485'
        ]
      ],
      'notes' => 'Test',
    ],
  ]
];

$client = new GuzzleHttpClient([
    'base_uri' => 'https://api.sandbox.paypal.com',
    'timeout'  => 2.0,
    'version' => 1.1
]);

$options = [
  'headers' => [
    'Authorization' => "Bearer $token",
  ],
  'multipart' => [
      [
          'name'     => 'input',
          'contents' => json_encode($input),
          'headers'  => ['Content-Type' => 'application/json']
      ],
      [
          'name'     => 'file1',
          'contents' => fopen($pdf, 'r'),
          'filename' => 'sample.pdf',
          'headers'  => ['Content-Type' => 'application/pdf']
      ],
  ]
];

$url = '/v1/customer/disputes/'.$disputeId.'/provide-evidence';

$headers = isset($options['headers']) ? $options['headers'] : [];
$body = new GuzzleHttpPsr7MultipartStream($options['multipart']);
$request = new GuzzleHttpPsr7Request('POST', $url, $headers, $body, '1.1');

$modify['set_headers']['Content-Type'] = 'multipart/related; boundary=' . $request->getBody()->getBoundary();

$request = GuzzleHttpPsr7modify_request($request, $modify);

$response = $client->send($request);

The guzzle code above still return {VALIDATION_ERROR - MISSING_OR_INVALID_REQUEST_BODY} and same result when I just do a normal multipart/form-data request.

What could be the issue? Any ideas or suggestion would very much help, thanks.

question from:https://stackoverflow.com/questions/65918020/paypal-customer-dispute-api-provide-evidence-always-returns-missing-or-invalid

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
$input = [
  'evidences' => [
    [
      'evidence_type' => 'PROOF_OF_FULFILLMENT',
      'evidence_info' => [
        'tracking_info' => [
          'carrier_name' => "FEDEX",
          'tracking_number' => '122533485'
        ]
      ],
      'notes' => 'Test',
    ],
  ]
];

This is your $input, if you json_encode() it, you get

{
    "evidences":
    [
        {
            "evidence_type":"PROOF_OF_FULFILLMENT",
            "evidence_info":{
                "tracking_info":{
                    "carrier_name":"FEDEX",
                    "tracking_number":"122533485"
                }
            },
            "notes":"Test"
            
        }
    ]
    
}

which does not matches with your request body,


I have changed your $input by inserting another square bracket,

$input = [
  'evidences' => [
    [
      'evidence_type' => 'PROOF_OF_FULFILLMENT',
      'evidence_info' => [
        'tracking_info' => [[
          'carrier_name' => "FEDEX",
          'tracking_number' => '122533485'
        ]]
      ],
      'notes' => 'Test',
    ],
  ]
];

Now it matches your curl request,

{
    "evidences":
        [
            {
                "evidence_type":"PROOF_OF_FULFILLMENT",
                "evidence_info":
                    {
                        "tracking_info":
                            [
                                {
                                    "carrier_name":"FEDEX",
                                    "tracking_number":"122533485"
                                    
                                }
                            ]    
                    },
                    "notes":"Test"             
            }
        ]
}

I hope it helps. If it doesn't work, then problem might lie somewhere else but the request body will match, you can try the guzzle call first.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...