Term vs match confusion

I have code that dynamically generates queries for a web service using queryBuilder, but it doesn't seem to work for a specific field / query type. I have exported the resulting queries as string to try and understand what is going wrong but I cannot see the error.

This query does not work:
{"bool" : {
"filter" : [ {
"range" : {
"INVOICE_DATE" : {
"from" : 1447438997610,
"to" : 1463160197610,
"include_lower" : true,
"include_upper" : true
}}},
{"term" : {"BILL_TO_NUMBER" : 100551}
}, {term" : {"CUSTOMER_PO_NUMBER" : "Gawin" }} ]}}

This does:
{"bool" : {
"filter" : [ {
"range" : {
"INVOICE_DATE" : {
"from" : 1447438997610,
"to" : 1463160197610,
"include_lower" : true,
"include_upper" : true
}}},
{"term" : {"BILL_TO_NUMBER" : 100551}},
{"term" : {"ORDER_NUMBER" : 1349929}} ]}}

The matching document for both queries is the same:
{ "_index": "cps_documents",
"_type": "invoice",
"_id": "819055",
"_score": null,
"fields": {
"CUSTOMER_PO_NUMBER": ["Gawin"],
"DOCID": [819055],
"INVOICE_DATE": [1456207200000],
"INVOICE_NUMBER": [1982323],
"ORDER_NUMBER": [1349929],
"SHIP_TO_NUMBER": [100552],
"DATESTORED": [1456276439000],
"BILL_TO_NAME": ["Action Heating & Air Conditioning"],
"BILL_TO_NUMBER": [100551]}

I thought maybe the mapping was different than I expected for CUSTOMER_PO_NUMBER
but it is using the standard analyzer and defined as a string...

"CUSTOMER_PO_NUMBER": {
"type": "string"
},

The following query with a slightly different syntax also works fine:
{
"bool": {
"must": [
{"match": {
"BILL_TO_NUMBER": "100551"
}},
{"match": {
"CUSTOMER_PO_NUMBER": "Gawin"
}},
{"range": {
"INVOICE_DATE": {
"from": 1447430782568,
"to": 1463151982568
}
}}
]
}}

Can you see what I am missing?

It turns out that a 'match' query worked fine for 'Gawin' but not a 'term query. I figured out that a 'term query' searches specifically for what is in the index where the 'match query' uses the standard analyzer.

If I reformat the query with a lower case 'g' then the term query is successful.