In the Recurly JS module, when a new subscription is being processed the function recurlyjs_subscribe_form_submit()
is called. This function has some code in it which creates a new account in Recurly. If the recurly module is being used in conjunction with the 'user' entity type there is some entity type specific code that allows the username and email address to be copied from the $user object to the new Recurly account. Otherwise, the account is basically just default/blank data.
This is a bit of a regression from previous versions of the module (and older Recurly JS API versions) where it appears like first name, last name, email and other data added as part of the billing information when creating a new subscription where also automatically applied to the account in Recurly. So, if you entered, "John Smith " into the old billing information forms the account in Recurly would get those values. This isn't the case anymore. When you create a new subscription the account's name is just the account code instead of the first/last entered in the billing form.
I think we can maybe hard-code first name, last name into module. Since they are required fields on the billing information form no matter what your AVS requirements are. This would require removing the post render callback that removes the 'name' attribute from those elements and then getting it out of $form_state and populating the new Recurly account object.
It would also be nice if there was a hook invoked that other modules could use which would allow them to populate things like the email address, and username of a Recurly object.
In my use case a subscription is linked to a custom membership entity. And there's a one-one relationship between the membership entity and a user account in Drupal. So a user is required to create a user account first, and I then have their username + email address. But, there's currently no way for me to inject them into the Recurly account when it's created.
Proposed resolution
Add hook_recurlyjs_account_alter(Recurly_Account $account, $entity, $plan_code)
and invoke it from within recurlyjs_subscribe_form_submit()
.
Consider moving this into an implementation of the new hook:
if ($entity_type == 'user') {
$recurly_account->email = $entity->mail;
$recurly_account->username = $entity->name;
}
Comments
Comment #2
walangitan CreditAttribution: walangitan at Chromatic for TheaterMania.com, Inc. commented@eojthebrave: Confirmed that this is an issue. I believe that this issue was first introduced in the update from V2 to V3 (and subsequently V4) of recurly.js and first addressed here for a default installation, but there is still more to do.
I think that the proposed resolution is a great course of action. Extending the creation/modification of a subscription so that the defaults can be overridden from other entities via hook. I'll look into translating the proposed resolution into a patch.
Comment #3
eojthebraveAnother, similar issue that I'm running into is the need to make use of the $subscription object created in recurlyjs_subscribe_form_submit() after the form is submitted. My use-case is wanting to log an event/transaction in Google Analytics. In previous versions of the module I added a submit handler to the form, and used the $form_state['recurly_status'] object that was added when validating the JS token. That code doesn't exist anymore though.
My suggestion in this case is to add something like the following:
If you remove the not necessary call to $recurly_account->create() (See #2854667: Display error message for declined credit cards) this will allow someone to modify the Recurly_Account, and Recurly_Subscription objects prior to saving them.
Comment #4
walangitan CreditAttribution: walangitan at Chromatic for TheaterMania.com, Inc. commentedSplitting up recurly_dme_modifications.patch into their corresponding issues. This work by eojthebrave tackles the proposed solution. I believe this can be the base from which we include a solution to resolve #3 as well.
Comment #5
eojthebraveIn my version I ended up re-writing this to use
hook_recurlyjs_subscription_alter()
, andhook_recurlyjs_new_subscription()
.I've attached my updated recurlyjs.api.php file.
And here's what I've got for the submit handler at the moment. This also includes some code that's not really related to this issue, like catching some validation errors for example. However, what it does do is remove the extra call to $recurly_account->create() which isn't necessary, so we can have a single point to alter the entire subscription object before it's saved. And then invoke the alter, and new_subscription hooks. Hopefully this is helpful.
Comment #6
markdorisonComment #7
markdorisonComment #8
markdorisonI have combined the patch and code in #5 into a single patch so it can be more easily reviewed.
Comment #9
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedI added an instance of both hooks defined in
recurlyjs.pages.inc
and I confirmed that they are being triggered when I submit the form at/user/1/subscription/signup/test-plan-2
. If I need to perform additional tests I can, just let me know what I should be testing.I also updated the patch to adding a space after the
:
in the error message.- Unable to create subscription:@error
+ Unable to create subscription: @error
Comment #10
markdorisonPatch no longer applies cleanly.
Comment #11
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedRe-rolled the patch.
Comment #12
markdorisonComment #14
markdorisonComment #15
markdorisonComment #16
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedComment #17
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedThis replicates the functionality from D7, but it is done with events instead of hooks. I did some limited testing and it seemed to work fine, but additional testing would be great.
Comment #18
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedComment #19
colanIn the updated README, I can see "recurlyjs" in the example code. So does this change only apply if you're using RecurlyJS and not Hosted Pages? Will Hosted Pages still work the old way? It would be helpful to clarify in provided comments.
Comment #20
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedGood catch. Yes, the events are only fired from the
recurlyjs
module. I reverted my changes to therecurly
README, and added them to therecurlyjs
README.Comment #21
colanThanks for that.
This calls are deprecated. See #2868491: Replace deprecated usage of SafeMarkup::checkPlain() for details. Sorry about not catching this earlier.
Comment #22
adamzimmermann CreditAttribution: adamzimmermann at Chromatic commentedAh, yes. When I reviewed the patch on that other issue I thought it looked familiar. Good catch. Updated the patch.
Comment #24
markdorison