3

I have a list with these fields: email, FNAME and LNAME. When I try to send merge_fields via Ajax, the Ajax return an error:

string(400) "{"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the 'errors' array.","instance":"f311cff1-ec28-4003-8dde-007bc0001688","errors":[{"field":"merge_fields.FNAME","message":"Data did not match any of the schemas described in anyOf."}]}"

JS:

app.subscribe = function() {
$(document).on('submit', '.form-course', function(e) {
    var fullName = $('#name').val(),
        arrName = fullName.split(' '),
        fname = arrName.slice(0, 1).join(' '),
        lname = arrName.slice(1, arrName.length).join(' ');

    var data = {
        'email' : $('#email').val(),
        "merge_fields": {
            "FNAME": fname,
            "LNAME": lname
        }
    };

    console.log(data);

    $.ajax({
        url: url+'/wp-admin/admin-ajax.php?action=ux_subscribe',
        method: 'POST',
        data: data,
        success: function(response) {
            gtag('send', 'event', 'Modal', 'subscribed', 'Subscription');
            fbq('track', 'CompleteRegistration');

            $('#modal').fadeOut(function() {
                // window.location.replace("./sucesso");
            });
        }, error: function(data) {
            alert('ERRO! Tente novamente mais tarde!');
        }
    });

    return false;
    });
};

PHP:

function ux_subscribe() {
    //GET via front-end form
    $apiKey = 'XXX'; //Generate an API key via: Account > Extras > Api Keys
    $listId = 'XXX'; //Find this via: Lists > List > Settings > List name and defaults
    $email = $_POST['email']; //GET via front-end form
    $fname = $_POST['fname']; //GET via front-end form
    $lname = $_POST['lname']; //GET via front-end form
    $auth = base64_encode( 'user:' . $apiKey );

    echo $fname;

    $json = json_encode([
        'email_address' => $email,
        'status'        => "subscribed", // Choices include: "subscribed", "unsubscribed", "cleaned", "pending"
        'merge_fields'  => array(
            'FNAME' => $fname,
            'LNAME' => $lname
        )
    ]);

    $memberId = md5(strtolower( $email ));
    $dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
    $url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listId . '/members/';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Authorization: Basic ' . $auth]);
    curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);

    $result = curl_exec($ch);

     var_dump($result);

    wp_die();
}

If I remove the variables and put a string, it works:

$json = json_encode([
        'email_address' => $email,
        'status'        => "subscribed", // Choices include: "subscribed", "unsubscribed", "cleaned", "pending"
        'merge_fields'  => array(
            'FNAME' => 'hello',
            'LNAME' => 'bye'
        )
    ]);

Someone knows why???

Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28
Maicon Furtado
  • 298
  • 1
  • 4
  • 15

2 Answers2

6

You can not send "empty" values to the API.

For example, this will work:

$fname = "joe";
$lname = "smith"
'merge_fields'  => array(
    'FNAME' => $fname,
    'LNAME' => $lname
)

But this would fail, notice how the lname is not defined.

$fname = "joe";
'merge_fields'  => array(
    'FNAME' => $fname,
    'LNAME' => $lname
)

Therefore you need some simple shorthand to supply "empty" values.

$fname = empty($fname) ? " " : $fname;
$lname = empty($lname ) ? " " : $lname ;
'merge_fields'  => array(
    'FNAME' => $fname,
    'LNAME' => $lname
)

I had a large array with 20 segments in it, and got the same error over and over, once I tossed in some proper empty() checking all was well...

Christian Žagarskas
  • 1,068
  • 10
  • 20
0

This is old but wanted to point out that your javascript ajax call sends this data:

var data = {
    'email' : $('#email').val(),
    "merge_fields": {
        "FNAME": fname,
        "LNAME": lname
    }
};

...But your PHP script is trying to find the post variables in:

$fname = $_POST['fname'];
$lname = $_POST['lname'];

Just update your ajax data to this:

var data = {
  'email' : $('#email').val(),
  'fname': fname,
  'lname' : lname
};
Dan S
  • 99
  • 6