
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
nestjs-braintree
Advanced tools
A module for Braintree reoccurring payments and transactions built for the Nestjs framework.
Using the Braintree node SDK.
NOTE! Currently building
$ yarn add nestjs-braintree
import { Module } from '@nestjs/common';
import { BraintreeModule } from 'nestjs-braintree';
import * as braintree from 'braintree';
@Module({
imports: [
BraintreeModule.forRoot({
environment: braintree.Environment.Sandbox,
merchantId: '',
publicKey: '',
privateKey: '',
}),
],
})
export default class AppModule {}
import { Module } from '@nestjs/common';
import { BraintreeModule } from 'nestjs-braintree';
@Module({
imports: [
BraintreeModule.forFeature(),
],
})
export default class SubModule {}
import { Module } from '@nestjs/common';
import { BraintreeModule } from 'nestjs-braintree';
import { ConfigModule, ConfigService } from 'nestjs-config';
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRootAsync({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
],
})
export default class AppModule {}
//config/braintree.ts
import * as braintree from 'braintree';
export default {
environment:
process.env.NODE_ENV == 'development'
? braintree.Environment.Sandbox
: braintree.Environment.Live,
merchantId: process.env.BRAINTREE_MERCHANT_ID,
publicKey: process.env.BRAINTREE_PUBLIC_KEY,
privateKey: process.env.BRAINTREE_PRIVATE_KEY,
};
Braintree is capable of making one off transactions
import { Module } from '@nestjs/common';
import { BraintreeModule, InjectBraintreeProvider } from 'nestjs-braintree';
import { ConfigModule, ConfigService } from 'nestjs-config';
class TransactionProvider {
constructor(
@InjectBraintreeProvider()
private readonly braintreeProvider: BraintreeProvider,
) {}
takePayment(amount: string, nonce: string) {
this.braintreeProvider.sale({
payment_method_nonce: nonce,
amount,
});
}
}
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRoot({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
],
providers: [TransactionProvider],
})
export default class AppModule {}
Avaliable methods relating to transactions are
braintreeProvider.sale(transaction: BraintreeTransactionInterface): Promise<BraintreeTransactionResultInterface>
braintreeProvider.refund(transactionId: string, amount?: string, orderId?: string): Promise<BraintreeTransactionResultInterface>
braintreeProvider.find(transactionId: string): Promise<BraintreeTransactionResultInterface>
The braintree SDK does offer additional methods. I will implement them soon hopefully
When using subscriptions with braintree, braintree will issue webhooks to your endpoint which you can use the decorators to handle those actions.
import { Module } from '@nestjs/common';
import {
BraintreeModule,
BraintreeWebhookModule,
BraintreeSubscriptionCanceled,
BraintreeSubscriptionExpired,
BraintreeWebhookHandler,
} from 'nestjs-braintree';
import { ConfigModule, ConfigService } from 'nestjs-config';
@BraintreeWebhookHandler()
class SubscriptionProvider {
@BraintreeSubscriptionCanceled()
canceled() {
console.log('subscription canceled');
}
@BraintreeSubscriptionExpired()
expired() {
console.log('subscription expired');
}
}
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRootAsync({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
BraintreeWebhookModule,
],
providers: [SubscriptionProvider],
})
export default class AppModule {}
The idea of the Braintree Webhook Module is to make implementation of actions a lot easier. For example we can build a provider like this one to cancel canceled subscriptions.
@BraintreeWebhookHandler()
export class SubscriptionProvider {
constructor(@InjectRepository(Subscription) private readonly subscriptionRepository: Repository<Subscription>) {}
async findByBraintreeId(braintreeId: string): Promise<Subscription|null> {
return await this.subscriptionRepository.find({
where: {
braintreeId,
},
});
}
async update(subscription: Subscription): Promise<boolean> {
return await this.subscriptionRepository.update(subscription);
}
@BraintreeSubscriptionCanceled()
async canceled(webhook: BraintreeWebhook) {
const subscription = await this.findByBraintreeId(webhook.subscription.id);
if (!subscription) {
return;
}
subscription.active = false;
await this.update(subscription);
}
}
Shortname | Braintree webhook name/const/key | NestJS decorator |
---|---|---|
Subscription Canceled | subscription_canceled | @BraintreeSubscriptionCanceled() |
Subscription Expired | subscription_expired | @BraintreeSubscriptionExpired() |
Subscription Charged Successfully | subscription_charged_successfully | @BraintreeSubscriptionChargedSuccessfully() |
Subscription Charged Unsuccessfully | subscription_charged_unsuccessfully | @BraintreeSubscriptionChargedUnsuccessfully() |
Subscription Went Active | subscription_went_active | @BraintreeSubscriptionWentActive() |
Subscription Went Past Due | subscription_went_past_due | @BraintreeSubscriptionWentPastDue() |
Subscription Trial Ended | subscription_trial_ended | @BraintreeSubscriptionTrialEnded() |
You can find out more about the webhooks here.
You may want to divert from the default routing of {your_domain}/braintree/webhook
for whatever reason. You can do so using the forRoot
method on the BraintreeWebhookModule
like so
@Module({
imports: [
ConfigModule.load('root/to/config/*/**.{ts,js}'),
BraintreeModule.forRootAsync({
useFactory: async (config: ConfigService) => config.get('braintree'),
inject: [ConfigService],
}),
BraintreeWebhookModule.forRoot({
root: 'replace-braintree',
handle: 'replace-webhook',
}),
],
providers: [SubscriptionProvider],
})
export default class AppModule {}
The above will result in your route for your braintree webhooks being {your_domain}/replace-braintree/replace-webhook
FAQs
Nestjs braintree module
The npm package nestjs-braintree receives a total of 8 weekly downloads. As such, nestjs-braintree popularity was classified as not popular.
We found that nestjs-braintree demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.