Skip to content

Commit 4453f18

Browse files
committed
Add support for new phone outputs
1 parent 05039f0 commit 4453f18

File tree

5 files changed

+140
-0
lines changed

5 files changed

+140
-0
lines changed

HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ History
1010
``ip_address`` parameter optional. Now the ``tag`` and at least one of the
1111
following parameters must be supplied: ``ip_address``, ``maxmind_id``,
1212
``minfraud_id``, ``transaction_id``.
13+
* Added ``billing_phone`` and ``shipping_phone`` properties to the minFraud
14+
Insights and Factors response models. These contain objects with information
15+
about the respective phone numbers. Please see `our developer
16+
site <https://dev.maxmind.com/minfraud/api-documentation/responses/>`_ for
17+
more information.
1318

1419
2.10.0 (2024-04-16)
1520
+++++++++++++++++++

minfraud/models.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,58 @@ class ShippingAddress:
758758
}
759759

760760

761+
@_inflate_to_namedtuple
762+
class Phone:
763+
"""Information about the billing or shipping phone number.
764+
765+
.. attribute:: country
766+
767+
The two-character ISO 3166-1 country code for the country associated with
768+
the phone number.
769+
770+
:type: str | None
771+
772+
.. attribute:: is_voip
773+
774+
This property is ``True`` if the phone number is a Voice over Internet
775+
Protocol (VoIP) number allocated by a regulator. The property is
776+
``False`` when the number is not VoIP. If the phone number was not
777+
provided or we do not have data for it, the property will be ``None``.
778+
779+
:type: bool | None
780+
781+
.. attribute:: network_operator
782+
783+
The name of the original network operator associated with the phone
784+
number. This field does not reflect phone numbers that have been ported
785+
from the original operator to another, nor does it identify mobile
786+
virtual network operators.
787+
788+
:type: str | None
789+
790+
.. attribute:: number_type
791+
792+
One of the following values: fixed or mobile. Additional values may be
793+
added in the future.
794+
795+
:type: str | None
796+
797+
"""
798+
799+
country: Optional[str]
800+
is_voip: Optional[bool]
801+
network_operator: Optional[str]
802+
number_type: Optional[str]
803+
804+
__slots__ = ()
805+
_fields = {
806+
"country": None,
807+
"is_voip": None,
808+
"network_operator": None,
809+
"number_type": None,
810+
}
811+
812+
761813
@_inflate_to_namedtuple
762814
class ServiceWarning:
763815
"""Warning from the web service.
@@ -1110,18 +1162,35 @@ class Factors:
11101162
11111163
:type: BillingAddress
11121164
1165+
.. attribute:: billing_phone
1166+
1167+
A :class:`.Phone` object containing minFrauddata related to the billing
1168+
phone used in the transaction.
1169+
1170+
:type: Phone
1171+
11131172
.. attribute:: shipping_address
11141173
11151174
A :class:`.ShippingAddress` object containing
11161175
minFraud data related to the shipping address used in the transaction.
11171176
1177+
:type: ShippingAddress
1178+
1179+
.. attribute:: shipping_phone
1180+
1181+
A :class:`.Phone` object containing minFrauddata related to the shipping
1182+
phone used in the transaction.
1183+
1184+
:type: Phone
1185+
11181186
.. attribute:: subscores
11191187
11201188
A :class:`.Subscores` object containing scores for many of the
11211189
individual risk factors that are used to calculate the overall risk
11221190
score.
11231191
"""
11241192

1193+
billing_address: BillingAddress
11251194
billing_address: BillingAddress
11261195
credit_card: CreditCard
11271196
disposition: Disposition
@@ -1133,12 +1202,14 @@ class Factors:
11331202
queries_remaining: int
11341203
risk_score: float
11351204
shipping_address: ShippingAddress
1205+
shipping_phone: Phone
11361206
subscores: Subscores
11371207
warnings: Tuple[ServiceWarning, ...]
11381208

11391209
__slots__ = ()
11401210
_fields = {
11411211
"billing_address": BillingAddress,
1212+
"billing_phone": Phone,
11421213
"credit_card": CreditCard,
11431214
"disposition": Disposition,
11441215
"funds_remaining": None,
@@ -1149,6 +1220,7 @@ class Factors:
11491220
"queries_remaining": None,
11501221
"risk_score": None,
11511222
"shipping_address": ShippingAddress,
1223+
"shipping_phone": Phone,
11521224
"subscores": Subscores,
11531225
"warnings": _create_warnings,
11541226
}
@@ -1241,13 +1313,30 @@ class Insights:
12411313
12421314
:type: BillingAddress
12431315
1316+
.. attribute:: billing_phone
1317+
1318+
A :class:`.Phone` object containing minFrauddata related to the billing
1319+
phone used in the transaction.
1320+
1321+
:type: Phone
1322+
12441323
.. attribute:: shipping_address
12451324
12461325
A :class:`.ShippingAddress` object containing
12471326
minFraud data related to the shipping address used in the transaction.
1327+
1328+
:type: ShippingAddress
1329+
1330+
.. attribute:: shipping_phone
1331+
1332+
A :class:`.Phone` object containing minFrauddata related to the shipping
1333+
phone used in the transaction.
1334+
1335+
:type: Phone
12481336
"""
12491337

12501338
billing_address: BillingAddress
1339+
billing_phone: Phone
12511340
credit_card: CreditCard
12521341
device: Device
12531342
disposition: Disposition
@@ -1258,11 +1347,13 @@ class Insights:
12581347
queries_remaining: int
12591348
risk_score: float
12601349
shipping_address: ShippingAddress
1350+
shipping_phone: Phone
12611351
warnings: Tuple[ServiceWarning, ...]
12621352

12631353
__slots__ = ()
12641354
_fields = {
12651355
"billing_address": BillingAddress,
1356+
"billing_phone": Phone,
12661357
"credit_card": CreditCard,
12671358
"device": Device,
12681359
"disposition": Disposition,
@@ -1273,6 +1364,7 @@ class Insights:
12731364
"queries_remaining": None,
12741365
"risk_score": None,
12751366
"shipping_address": ShippingAddress,
1367+
"shipping_phone": Phone,
12761368
"warnings": _create_warnings,
12771369
}
12781370

tests/data/factors-response.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@
122122
"distance_to_ip_location": 5465,
123123
"is_in_ip_country": false
124124
},
125+
"billing_phone": {
126+
"country": "US",
127+
"is_voip": true,
128+
"network_operator": "Verizon/1",
129+
"number_type": "fixed"
130+
},
125131
"credit_card": {
126132
"issuer": {
127133
"name": "Bank of No Hope",
@@ -159,6 +165,12 @@
159165
"latitude": 35.704729,
160166
"longitude": -97.568619
161167
},
168+
"shipping_phone": {
169+
"country": "CA",
170+
"is_voip": true,
171+
"network_operator": "Telus Mobility-SVR/2",
172+
"number_type": "mobile"
173+
},
162174
"subscores": {
163175
"avs_result": 0.01,
164176
"billing_address": 0.02,

tests/data/insights-response.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@
122122
"distance_to_ip_location": 5465,
123123
"is_in_ip_country": false
124124
},
125+
"billing_phone": {
126+
"country": "US",
127+
"is_voip": true,
128+
"network_operator": "Verizon/1",
129+
"number_type": "fixed"
130+
},
125131
"credit_card": {
126132
"issuer": {
127133
"name": "Bank of No Hope",
@@ -159,6 +165,12 @@
159165
"latitude": 35.704729,
160166
"longitude": -97.568619
161167
},
168+
"shipping_phone": {
169+
"country": "CA",
170+
"is_voip": true,
171+
"network_operator": "Telus Mobility-SVR/2",
172+
"number_type": "mobile"
173+
},
162174
"warnings": [
163175
{
164176
"code": "INPUT_INVALID",

tests/test_models.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,21 @@ def test_issuer(self):
246246
self.assertEqual(phone, issuer.phone_number)
247247
self.assertEqual(True, issuer.matches_provided_phone_number)
248248

249+
def test_phone(self):
250+
phone = Phone(
251+
{
252+
"country": "US",
253+
"is_voip": True,
254+
"network_operator": "Verizon/1",
255+
"number_type": "fixed",
256+
}
257+
)
258+
259+
self.assertEqual("US", phone.country)
260+
self.assertEqual(True, phone.is_voip)
261+
self.assertEqual("Verizon/1", phone.network_operator)
262+
self.assertEqual("fixed", phone.number_type)
263+
249264
def test_warning(self):
250265
code = "INVALID_INPUT"
251266
msg = "Input invalid"
@@ -327,7 +342,9 @@ def factors_response(self):
327342
"device": {"id": "b643d445-18b2-4b9d-bad4-c9c4366e402a"},
328343
"email": {"domain": {"first_seen": "2014-02-23"}, "is_free": True},
329344
"shipping_address": {"is_in_ip_country": True},
345+
"shipping_phone": {"is_voip": True},
330346
"billing_address": {"is_in_ip_country": True},
347+
"billing_phone": {"is_voip": True},
331348
"funds_remaining": 10.01,
332349
"queries_remaining": 123,
333350
"risk_score": 0.01,
@@ -367,8 +384,10 @@ def check_insights_data(self, insights, uuid):
367384
self.assertEqual("reject", insights.disposition.action)
368385
self.assertEqual(True, insights.email.is_free)
369386
self.assertEqual("2014-02-23", insights.email.domain.first_seen)
387+
self.assertEqual(True, insights.shipping_phone.is_voip)
370388
self.assertEqual(True, insights.shipping_address.is_in_ip_country)
371389
self.assertEqual(True, insights.billing_address.is_in_ip_country)
390+
self.assertEqual(True, insights.billing_phone.is_voip)
372391
self.assertEqual(uuid, insights.id)
373392
self.assertEqual(10.01, insights.funds_remaining)
374393
self.assertEqual(123, insights.queries_remaining)

0 commit comments

Comments
 (0)