伙计们,我正在尝试通过托管字段将reactTree集成到reactJs中。现在我能够将它集成到我的项目中,并使其工作并能够付款。
我面临的问题是,当我尝试输入卡号4444 4444 4444 4444
时,我希望得到一个错误,就像我在dropin中得到的但是它不会引发错误。如果我用上面错误的卡号输入2或3个额外的4,我会收到错误。有人可以告诉我,我做错了什么。感谢
// Some Imports
import BrainTree from 'braintree-web';
var dropin = require('braintree-web-drop-in');
export class Checkout extends Component {
state = {
valueEntered: 5,
showSuccessMessage: false,
showErrorMessage: false,
};
componentWillMount() {
this.props.getClientToken();
}
checkoutPayment(nounce) {
this.props.Checkout({
paymentValue: this.state.valueEntered,
paymentMethodNounce: nounce,
});
}
// ONCE WE RECIEVE THE TOKEN THIS FUNCTION WILL BE CALLED SOMEHOW
// AND HERE THE BRAINTREE WILL BE INTIALIZED
componentWillReceiveProps(nextProps) {
var button = document.querySelector('#submit-button');
if (nextProps.user.clientToken && nextProps.user.clientToken != null && nextProps.user.clientToken !== this.props.user.clientToken) {
BrainTree.client.create(
{
authorization: nextProps.user.clientToken,
},
(err, clientInstance) => {
let me = this;
if (err) {
console.error(err);
return;
}
BrainTree.hostedFields.create(
{
client: clientInstance,
styles: {
input: {
'font-size': '14px',
'font-family':
'helvetica, tahoma, calibri, sans-serif',
color: '#3a3a3a',
},
':focus': {
color: 'black',
},
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111',
},
cvv: {
selector: '#cvv',
placeholder: '123',
},
expirationMonth: {
selector: '#expiration-month',
placeholder: 'MM',
},
expirationYear: {
selector: '#expiration-year',
placeholder: 'YY',
},
postalCode: {
selector: '#postal-code',
placeholder: '90210',
},
},
},
(err, hostedFieldsInstance) => {
if (err) {
console.error(err);
return;
}
hostedFieldsInstance.on('validityChange', function(
event
) {
var field = event.fields[event.emittedBy];
if (field.isValid) {
if (
event.emittedBy === 'expirationMonth' ||
event.emittedBy === 'expirationYear'
) {
if (
!event.fields.expirationMonth
.isValid ||
!event.fields.expirationYear.isValid
) {
return;
}
} else if (event.emittedBy === 'number') {
document.querySelector(
'#card-number'
).nextSibling.innerHTML =
'';
}
// Apply styling for a valid field
document
.querySelector('#' + field.container.id)
.closest('.form-group')
.classList.add('has-success');
} else if (field.isPotentiallyValid) {
// Remove styling from potentially valid fields
document
.querySelector('#' + field.container.id)
.closest('.form-group')
.classList.remove('has-warning');
document
.querySelector('#' + field.container.id)
.closest('.form-group')
.classList.remove('has-success');
if (event.emittedBy === 'number') {
document.querySelector(
'#card-number'
).nextSibling.innerHTML =
'';
}
} else {
// Add styling to invalid fields
document
.querySelector('#' + field.container.id)
.closest('.form-group')
.classList.add('has-warning');
// Add helper text for an invalid card number
if (event.emittedBy === 'number') {
document.querySelector(
'#card-number'
).nextSibling.innerHTML =
'Looks like this card number has an error.';
}
}
});
hostedFieldsInstance.on('cardTypeChange', function(
event
) {
// Handle a field's change, such as a change in validity or credit card type
if (event.cards.length === 1) {
document.querySelector(
'#card-type'
).innerHTML =
event.cards[0].niceType;
} else {
document.querySelector(
'#card-type'
).innerHTML =
'Card';
}
});
button.addEventListener('click', event => {
event.preventDefault();
hostedFieldsInstance.tokenize(
(err, payload) => {
let paymentComponnet = me;
if (err) {
console.error(err);
return;
}
paymentComponnet.checkoutPayment(
payload.nonce
);
// This is where you would submit payload.nonce to your server
// alert('Submit your nonce to your server here!');
}
);
});
}
);
}
);
}
}
handleChange = (field, value) => {
this.setState({
[field]: value,
});
};
// HERE WE WILL RENDER OUR HTML
render() {
let paymentValue = this.state.valueEntered;
return (
<div styleName="organization-profile">
<div className="form-group">
<label for="focusedInput">Amount</label>
<input
className="form-control"
id="amount"
name="amount"
type="tel"
min="1"
placeholder="Amount"
value={paymentValue}
onChange={e => {
this.handleChange('valueEntered', e.target.value);
}}
/>
</div>
<div className="panel panel-default bootstrap-basic">
<div className="panel-heading">
<h3 className="panel-title">Enter Card Details</h3>
</div>
<form className="panel-body">
<div className="row">
<div className="form-group col-xs-8">
<label className="control-label">
Card Number
</label>
<div
className="form-control"
id="card-number"
/>
<span className="helper-text" />
</div>
<div className="form-group col-xs-4">
<div className="row">
<label className="control-label col-xs-12">
Expiration Date
</label>
<div className="col-xs-6">
<div
className="form-control"
id="expiration-month"
/>
</div>
<div className="col-xs-6">
<div
className="form-control"
id="expiration-year"
/>
</div>
</div>
</div>
</div>
<div className="row">
<div className="form-group col-xs-6">
<label className="control-label">
Security Code
</label>
<div className="form-control" id="cvv" />
</div>
<div className="form-group col-xs-6">
<label className="control-label">Zipcode</label>
<div
className="form-control"
id="postal-code"
/>
</div>
<button
id="submit-button"
className="btn btn-success btn-lg center-block"
>
Pay with <span id="card-type">Card</span>
</button>
</div>
</form>
</div>
</div>
);
}
}
export default Checkout;
答案 0 :(得分:1)
完全披露:我在Braintree工作。如果您有任何其他问题,请随时联系support。 子>
当字段失去焦点时,Drop-in UI仅显示错误消息。根据您的初始帖子,如果用户输入无效的卡号,您似乎正在尝试显示错误消息。 .on('validityChange')
事件仅在isValid
或isPotentiallyValid
布尔值更改时发出。在使用数字4444 4444 4444 4444
的示例中,isValid
布尔值保持为false,isPotentiallyValid
在您输入第19位数字之前不会从true切换为false。您可以查看这些检查背后的逻辑here。
根据您所描述的内容,您似乎想要使用.on('blur')
。当字段失去焦点时会发出此事件,此时您将能够对卡对象执行检查以确定是否显示错误消息。此外,您可能希望更新条件,因为您的else if (field.isPotentiallyValid)
子句将捕获该事件 - 如果卡号无效,您可以删除此子句以始终显示错误消息。
hostedFieldsInstance.on('blur', function (event) {
var field = event.fields[event.emittedBy];
if (field.isValid) {
// Handle valid field
} else {
// Add styling to invalid fields
}
});