Colin Devroe

Reverse Engineer. Blogger.

JSON Feed to Twitter using PHP

In 2009 I scrawled together a simple PHP script that tweeted links based on an RSS feed. I then updated it to support OAuth and open sourced it on GitHub.

I haven’t really touched it since (though I get about 3 emails a month about it). Just a small update here and there.

This morning, with all of the JSON Feed hubbub going on, I decided to recreate that same simple script to parse JSON Feed rather than RSS. I also updated to the latest release of the PHP Twitter OAuth class by Tijs Verkoyen.

You can download the latest release or clone the repository on GitHub.

This took me mere minutes thanks to JSON Feed being much easier to deal with.

Migrating Subscriptions from one Stripe account to another

One of my recent client programming projects (hire me here) was to help a company migrate all customers, cards, plans, and subscriptions from one Stripe account to another as a result of an acquisition. I hadn’t needed to do anything like this in the past and I ended up fumbling my way through a few of the steps. So, I thought it worth the effort to jot down the process.

Here is a graphic of the overall process with notes to follow below.

Stripe Migration

I made some notes along the way during this project. Using the numbers above, here is the process step-by-step and some things you’ll want to keep in mind before you begin.

  1. Send an email to to request Customer and Card migration from Account A to Account B.
    • Remember that both accounts need to be activated
    • Stripe cannot transfer live accounts into test accounts (a shame)
  2. Stripe transfers Customer and Card information from Account A to Account B
    • Stripe cannot “schedule” this transfer for an exact date or time
    • Stripe can run the migration more than once should new Customers be added
    • Customer IDs are retained from one account to another
    • Card IDs cannot be retained
    • Stripe will not migrate Plans or Subscriptions
  3. Transfer Plans from Account A to Account B
    • Retain all plan information (recommended)
    • The most crucial piece to keep the same is plan_id
    • You may want to make adjustments to “Statement Description” at this time if the business name has changed
  4. Transfer Active Subscriptions from Account A to Account B
    • There is no need to transfer cancelled or inactive accounts
    • During the transfer, request Subscription on Account A to cancel at period end
    • Create a new Subscription on Account B based on plan_id, using billing_cycle_anchor will allow the Subscription on Account B to begin the moment the Subscription on Account A is cancelled
  5. (not in graphic) Verify all Plan and Subscription information has been moved

Whether you’re using Stripe’s excellent API to migrate your Plans and Subscriptions or doing it manually via their admin the process is basically the same. The customer I was working with had nearly 5,000 customers and over 1,000 active Subscriptions on 4 Plans. So writing a script to do this saved huge amounts of time.

Aside: How do you calculate whether or not it is worth building a script to do this or doing it yourself via Stripe’s admin? Well, the pessimistic view would be something like this comic from the always excellent XKCD re: automation. However, the more practical approach is this comic from XKCD titled Is It Worth The Time?

How did I write the code? Depending on your exact needs and your familiarity in different languages you may want to find a completely different approach to the one I took. However, I’m a PHP guy, this is what I did.

I started by doing a search on Github for “Stripe Migration” (always worth starting here) which led me to this set of simple scripts from Nyalex for migrating Plans and Subscriptions on Stripe from one account to another. This likely saved me 5 to 10 hours of development. (Thanks Nyalex!) I then reached out to him on Twitter to let him know I was about to use his script. We had a nice conversation that helped me to get my head around how his scripts worked.

My modifications to Nyalex’s script were fairly minimal but vital. Since he hadn’t used the scripts in some time they fell out-of-date with Stripe’s latest API version. So I had to make some subtle updates to account for those. Also, the client was using Easy Digital Downloads, a WordPress ecommerce plugin, as their backend so I had to write a few SQL queries to update the Subscription IDs in EDD’s customer table as the process ran. I plan on writing a Pull Request for Nyalex so that I can help keep his set of scripts up-to-date for future uses.

There were, of course, a few hiccups when running the scripts.

First, the client’s server would time out if I tried to process all 4,800 accounts at once. Each account creates several Stripe API calls (about 7) so even with Stripe’s limit of 100 accounts at-a-time that is still a hefty 700 API calls. So understandably I had to find the right number that the server’s setup could handle without choking. I also slimmed down the number of API calls slightly from the default. I did this by creating some mock API calls for the cancel and create Subscription calls and let the script run a few times until I found the right number. For this particular client it was 20 accounts at a time being processed. Which meant the script ran over 200 times to complete the process. Because I was purposefully doing this manually, rather than setting up the script to run end-over-end, this process took a little over an hour.

Second, prior to creating those mock calls I accidentally duplicated a few subscriptions for 23 accounts and needed to go back and manually cancel them all before re-running the script. I recommend not doing this. Again, it is a drawback that Stripe cannot migrate live Accounts as Test accounts so that you can do test runs on this sort of thing but it is understandable.

And, lastly, I didn’t properly create a log file for all of the transfers as they were done so I had to manually save the output of Nyalex’s script to a text file. I think I’d like to update the scripts to create a log file of old subscription ID, customer email address, and new subscription ID at the very least. This would have saved me a lot of time and would give me a “back up” of sorts should any customers have been missed. Also, since the scripts only attempt to migrate active Subscriptions it would have been nice to extend the scripts to log inactive Customers too just as a double-check that those Customers were looked at.

Overall this was an interesting project to take on and I’m hoping that my knowledge from this project will get reused in the future. If you need to migrate from one Stripe account to another please reach out.

GitHub is now more affordable


We couldn’t be more excited to announce that all of our paid plans on now include unlimited private repositories. GitHub will always be free for public and open source projects, but starting today there are just two ways to pay for

$7/m for personal accounts, $9/m per user for organizations (only $25/m for the first 5 users).

This makes using about as affordable as possible for anyone that needs collaborative, online version control. At Plain we had switched to BitBucket because their model was better for our specific usage (lots of private repos, low head count). But this change could bring us back someday.

I’ve written a few times about how git isn’t just for programmers. The same goes for GitHub. I think their way forward, and for growth, would be to begin separating the experience for different uses like writers, designers, researchers. I wonder if making it more affordable is a step towards that.

RSS to Twitter using PHP

Update January 19, 2010: This script is now available on GitHub. Go forth and fork.

Today I noticed that my now ancient PHP script to update Twitter automatically using PHP/cron needed to be updated. It turns out that Twitter stopped recognizing URLs with ? in them as clickable links. Here is an example tweet where you’ll notice this happening.

I could have told Twitter and asked that they update the way they handle URLs but in reality my script was old, slow, too long, and shouldn’t include ? anyway so I figured I’d write a new one from scratch that included my short URL scheme.

So, here is the PHP script to parse an RSS feed and send the posts to Twitter. It includes a caching mechanism so that you won’t have duplicate URLs posted to Twitter. If you want it, take it. However, if you are better than I am at PHP (most 6yr. olds are better than I am at programming) then I ask that you fork the script on Gist and try to improve it.

Update Dec. 6 @ 5:34p: Kyle Slattery, follow Viddler team member, loves him some Ruby on Rails. As such he’s offered up this version of the script rewritten in Ruby.

Next up we have Anthony Sterling, self-proclaimed “PHP addict”, who has rewritten the script to make the configuration a bit easier. He also changed the way the cache is saved. He’s using a hashed version of the title for each post as his key. I do not believe this to be the best way to go, since post titles can easily change after publishing – but I do like that the script is about 20 lines shorter and the code is arguably cleaner.

Thanks to both Kyle and Anthony for their versions. Lets keep this going and see if we can get this script much more succinct, stable, faster, and usable by others?