curl - Paypal curl_setopt($ch, CURLOPT_POSTFIELDS with PHP variables

Solution:

Create your JSON string like this:

$data = [
    'plan_id' => $planID,
    'start_time' => $startTime,
    'application_context' => [
        'brand_name' => 'Sleep Happy Mattress',
        'locale' => 'en-US',
        'shipping_preference' => 'SET_PROVIDED_ADDRESS',
        'user_action' => 'SUBSCRIBE_NOW',
        'payment_method' => [
            'payer_selected' => 'PAYPAL',
            'payee_preferred' => 'IMMEDIATE_PAYMENT_REQUIRED'
        ],
        'return_url' => 'https://example.com/returnUrl',
        'cancel_url' => 'https://example.com/cancelUrl'
    ],    
];

Then you can check that the nesting etc is correct (please note I don't know if the above is correct, I just copied it from your question), and if you json_encode it you will create well-formed JSON.

$jsonEncoded = json_encode($data);

Answer

Solution:

Do not specify nor include a start_time, unless you want problems with amounts not showing in checkout.

Your problem is you did not keep quotes around the variable values, which is necessary for JSON string syntax. Observe:

\"plan_id\": \"$planID\",

Using json_encode() to construct your string from an array object would be better.

Source