My response below is a little bit of a rant against having state machine gems in Rails projects rather than critique of your post per se, but hopefully some solid points to consider (and debate?):
I don't think I would break out the state machine logic into another model and then mix it right back in unless you need to do exactly the same thing in two or more model classes. Basically, if you're not DRYing up code, you're just obscuring and all you've done is complicate your code design with little gain to show for it other than not having to look at the state machine code every time you open the Purchase class. Skinny models is about single concerns for any given model more so than "small" files [1] that are pleasing to read. In the scenario demonstrated in the blog, it feels like you're just hiding "ugly DSL" from every day viewing and I'd also be concerned about the implementation being susceptible to the Anemic Domain Model
anti-pattern [2] where you start separating data and processes from the
object that should be responsible for it. Do this enough throughout your whole project and you'll have a hard time piecing everything together in a debugging session when something goes sour and the whole program's no longer in your head.
I think I would reduce the Purchase model's concern to nothing more than making the payment request to the gateway and recording the state thereof. To track what's actually being bought, I'd introduce an Order model which gets updated as "paid" upon successfully capturing the funds. In general, you should have a rich supporting cast of models around your ordering and purchasing activities that are concerned with their own single purposes. If you have a complex set of objects to orchestrate for making a purchase, use a Builder [3] class to handle these actions as appropriate. This approach, to me, is a lot easier to test and follow than reading a lot of DSL describing states and transitions.
One of the problems I have with state machine gems in Rails projects in general is that they tend to be injected into projects that don't need them, thus making the code a lot harder to read and follow than it needs to be. Their use is also further complicated by also using ActiveRecord callbacks and validations on the models that make use of the model's states and this can play havoc on the state machine's callbacks, guards, and transitions. In more than one project, I've seen this at its worst with around filters in controllers *also* doing something on the model's states where a developer essentially gave up on understanding the state-machine's DSL and pounded the proverbial square peg into the round hole to get his objective accomplished. When all three are used together to orchestrate state transitions and actions to take transitioning to new states, it gets to be a huge testing and debugging nightmare very, very quickly, esp. for the developers that didn't put it together in the first place.