PayPal Server SDK migration: the 1.0.0 renames and the 2.0.0 options object
paypal sdk migration 6958 tracked change records
The PayPal Server SDK (@paypal/paypal-server-sdk) shipped two breaking majors back to back. The 1.0.0 release renamed every controller method: the ordersCreate and authorizationsCapture style names became createOrder and captureAuthorizedPayment, fifteen renames across the orders and payments controllers. Then 2.0.0 kept the new names but changed the calling convention itself: every method that took positional parameters now takes a single options object. Code migrated by hand for 1.0.0 broke again a release later. Both halves are mechanical, both touch every call site, and that is the profile of a codemod job.
The 1.0.0 controller renames
This list is read directly from the mendapi migration pack registry (paypal-server-sdk-v1-controller-renames) at page build time, so it matches what the codemod actually does:
- ordersController: rename legacy method calls to their 1.0.0 names
- paymentsController: rename legacy method calls to their 1.0.0 names
The full fifteen-pair rename map was verified token by token against the SDK source at tags 0.6.1 and 1.0.0: ordersCreate to createOrder, ordersCapture to captureOrder, authorizationsVoid to voidPayment, capturesRefund to refundCapturedPayment, and the rest of both controller families. Each rename applies from a whitelisted map and only on calls anchored to an ordersController. or paymentsController. member chain, so a same-named method on an unrelated object is never touched. One honest wrinkle from the release history: the rename actually landed in 0.7.0 and 1.0.0 kept it, so the pack mends pre-0.7.0 call sites no matter which release you jump to.
The 2.0.0 calling-convention change
The second pack (paypal-server-sdk-v2-options-object) handles the structural half:
- Wrap positional controller-method arguments into the 2.0.0 options object (requestOptions stays positional)
In 1.0.0 a capture call was positional: paymentsController.captureAuthorizedPayment(authId, undefined, requestId). In 2.0.0 the same call wraps every former positional parameter into one object with named keys, while requestOptions stays behind as a second positional argument. A find-and-replace cannot do this rewrite, because the correct key for each position depends on which method you are calling. The pack carries the per-method parameter order extracted mechanically from the 1.0.0 signatures, so the position-to-key mapping is deterministic, and arguments are split with a string-aware bracket-depth scanner rather than a naive comma split, so nested calls and string literals containing commas are safe.
What the codemod refuses to touch
A migration tool earns trust by what it leaves alone. Multi-line call sites do not match the options-object rule at all: the rewrite simply skips them, which is the conservative direction. A call whose first argument is already an object literal is treated as migrated and left untouched, so running the pack twice is a no-op. Template literals and comments inside an argument list also stop the rewrite. Every rule in both packs is locked by golden-fixture regression tests with negative controls, so a rule that starts over-firing fails our build before it reaches your repo.
Preview each migration as one diff
Both packs run locally as a dry run by default. On the bundled fixture repos, each pack rewrites two files and writes a unified patch you can read before anything is applied:
npx mendapi scan # -> which files touch the PayPal SDK, with line numbers mendapi fix --migration paypal-server-sdk-v1-controller-renames # -> dry run: changes.patch + fix-report.json, nothing applied mendapi fix --migration paypal-server-sdk-v2-options-object # -> the calling-convention half, same dry-run discipline mendapi fix --migration paypal-server-sdk-v2-options-object --apply # -> applies the reviewed diff
Nothing leaves your machine at any step; zero network calls is the default and only mode. The report records which rule fired where, and every rewritten file carries a syntax-check verdict, so review is a read of the patch, not an audit of the tool.
The part no codemod fixes
Honest scope: the packs handle the mechanical rewrites. They do not decide how your code should adopt new SDK behavior: response typing differences, error-class changes, or code that picks a controller method dynamically at runtime. The tracked PayPal history counts 1198 breaking or deprecation entries, and the platform-behavior ones stay not code-fixable by verdict, because pretending a codemod covers them is how migrations go wrong.
Related
- PayPal API breaking changes: complete tracker — every tracked entry with fixability verdicts.
- Stripe Payment Records migration — the other fintech provider where breaking changes land in payment paths.
- Migration pack catalog — every deterministic fix mendapi ships.