Using dependency injection for Node payment system
It looks good to me, very SOLID.

Here are a couple of suggestions:

I'm not really seeing the value in the PaymentRepository layer. If the Stripe wrapper is following a strict interface then just import it directly as your payment gateway i.e.

import PaymentGateway from './stripe';
...
charge(new PaymentGateway());


This still gives you the flexibility &amp; testability but with one less layer. If you introduced a new payment gateway all that changes is the import e.g.

import PaymentGateway from './worldpay.js'


Also, you may have gone a bit overboard with your use of async / await. This code:

async x() {
  try {
    const result = await promise();
    return result;
  } catch (e) {
    throw e;
  } 
}


Is effectively the same as:

x() { 
  return promise();
}


Because you don't actually use the result (or error) until further up the callstack. Although having said that, you might want to consider deserializing your Stripe API responses to avoid leaking internal data through the layers.