I would like to programatically renew memberships when a transaction has been completed in Woocommerce.
I want my members to have a more consistent experience and since I do a lot through the woocommerce store already, I wanted to do renewals and new memberships.

I need some confirmation to see if I'm doing this correctly though - For a new membership, I think it is straight forward to simply do:

--confirm no membership entries exist already for this contact_id

$result = civicrm_api3('Membership', 'get', [ 'sequential' => 1, 'contact_id' => 15947, ]);

--Create a new membership entry

$result = civicrm_api3('Membership', 'create', [ 'membership_type_id' => "Registered Participant", 'contact_id' => 15947, 'start_date' => 20200513, 'end_date' => 20210513, 'source' => "Payment", ]);

But for a renewal, I don't want to keep adding additional lines of membership entries so I am thinking same above except if an entry is found, issue a create with the ID and it should renew it correctly?

--confirm no membership entries exist already for this contact_id

$result = civicrm_api3('Membership', 'get', [ 'sequential' => 1, 'contact_id' => 15947, ]);

-- Entry found so renew

$result = civicrm_api3('Membership', 'create', [ 'membership_type_id' => "Registered Participant", 'contact_id' => 15947, 'start_date' => 20200513, 'end_date' => 20210513, 'source' => "Payment", 'status_id' => "Current", 'id' => 8746, ]);

So the only difference between a new membership and a renewal is the 'id' and 'status_id' ?

2 Answers 2


So this was my solution. Using Wordpress triggers, its fired off whenever an order is submitted and successfully paid. If it contains the product to create new/or renew then. I hope it helps someone. I still need to add some error traps, otherwise should work fine for my setup.

 # Product ID for the registered participant is noted below
 #error_log("Line items: $item\n");
 if ($item["product_id"] == 33706) {
     $result = civicrm_api3('Membership', 'get', [ 'sequential' => 1, 'contact_id' => $contactid, ]);
     if ($result["count"] == 0) {
         #create new membership entry
         #start date/end date will be today to 1 year out
         $start_date = date("Ymd");
         $end_date = date('Ymd', strtotime($start_date. ' + 1 year'));
         $result = civicrm_api3('Membership', 'create', [ 'membership_type_id' => "Registered Participant", 'contact_id' => $contactid, 'start_date' => $start_date, 'end_date' => $end_date, 'source' => $item["order_id"], ]);
     } else {
         #renew membership
         $current = $result[values][0];
         $current_start_date = $current['start_date'];
         $current_end_date = $current['end_date'];
         $membership_id = $result['id'];
         if ($current_end_date < date()) {
             $new_start_date = date("Ymd");
         } else {
             $new_start_date = $current_end_date;
         $new_end_date = date('Ymd', strtotime($new_start_date. ' + 1 year'));

         $result = civicrm_api3('Membership', 'create', [ 'membership_type_id' => "Registered Participant", 'contact_id' => $contactid, 'start_date' => $new_start_date, 'end_date' => $new_end_date, 'source' => $item["order_id"], 'status_id' => "Current", 'id' => $membership_id, ]);

I have a feature called "auto-memberships" in this extension: https://github.com/adixon/ca.civicrm.contributionrecur

It might almost do what you want (it'll update existing memberships, won't create new ones, but you could add that).

There's a little record that connects a payment with a membership, which is nice if you add it, so that you can more easily identify payments that haven't yet been connected.

  • Not really what I'm after. Similar but looking to use in a Wordpress plugin since it will be fired by the Woocommerce triggers. If no one tells me otherwise, I will go ahead and write it up as I explain above and see if it works. Thanks. Commented May 14, 2020 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.